728x90
반응형

이 글은 Realm을 사용하며 Java8을 사용하기 위해 jackOption을 설정한 개발자를 위한 글이다.


Realm을 추가하고 앱을 실행하면 Application에서 Realm.init()부터 에러가 나는것을 볼 수 있다.


java.lang.ExceptionInInitializerError: RealmTransformer doesn't seem to be applied.

                                           Please update the project configuration to use the Realm Gradle plugin.

   See https://realm.io/news/android-installation-change/

at io.realm.RealmConfiguration.<clinit>(RealmConfiguration.java:78)

at io.realm.RealmConfiguration$Builder.initializeBuilder(RealmConfiguration.java:474)

at io.realm.RealmConfiguration$Builder.<init>(RealmConfiguration.java:460)

at io.realm.Realm.init(Realm.java:201)


만약 저 링크에 있는 것처럼 Gradle 설정을 잘 따라 했다면 JackOption을 사용했는지 확인해봐야 한다.


만약 본인이 Lambda을 사용하기 위해 아래와 같이 JackOption을 사용했다면

Retrolambda를 사용해야 Realm을 사용 할 수 있다.


이 에러를 해결하기 위해서는 jackOptions을 제거하고 Retrolambda를 추가해야한다.


본인 프로젝트 build.gradle




Module build.gradle




출처

https://blog.realm.io/android-installation-change/

https://stackoverflow.com/questions/41153879/realm-android-realmtransformer-doesnt-seem-to-be-applied

https://github.com/evant/gradle-retrolambda

http://tiii.tistory.com/5

728x90
반응형
728x90
반응형

Realm은 Android에서 사용하던 SQLite와는 다른 C++ 코어 기반 DB입니다.


(출처: https://speakerdeck.com/realm/realm-introduction-seoul-meetup-10)



그리고 기존 RDB개념이 아닌 Object를 저장하는 개념입니다.


  

(출처: https://speakerdeck.com/realm/realm-introduction-seoul-meetup-10)



이렇게 사용함으로써 RDB개념에 대해 잘 모르는(저도 잘 모릅니다) 개발자에게 Realm은 그냥 객체를 사용하는데 알아서 DB에 쓰고 읽는 효과를 볼 수 있습니다.


하지만 제가 Realm을 쓰면서 놀란게 하나가 있습니다.


바로 모델 클래스를 상속 시킬수가 없다는 것입니다.


나닛?!


그래서 이번 블로그에서는 Realm을 사용하면서 발생하는 이슈중 하나인 RealmObject 상속으로 인한 모델 구조 변경에 대해서 이야기하려고합니다.


1. is-a관계 has-a관계로 만들기


예를 들어 Log클래스와 User클래스가 있고 User클래스는 Log클래스를 상속 받는 구조 입니다.

public class Log extends RealmObject {
public long createdTs;
public long updatedTs;
}

public class User extends Log {
public String name;
public int age;
public String email;
}

is-a관계로 모델을 구성 했을 때 Realm에서는 이런 오류가 발생합니다.

Valid model classes must either extend RealmObject or implement RealmModel.





출처: https://github.com/realm/realm-java/issues/2691

출처: https://github.com/realm/realm-java/issues/761


is-a관계가 언제 될지는 모르겠지만 아마 안될꺼같아요.


그래서 모델 클래스를 has-a관계로 바꿔야합니다.

public class User extends RealmObject {
public Log log;
public String name;
public int age;
public String email;
}


2. 상속구조 구현하기


is-a관계를 has-a관계로 바꾸면서 다형성(Polymorphism)과 유사한 형태를 만들어 보려고 합니다.


public interface ILog extends RealmModel {
Log getLog();
}
public interface IUser extends ILog {
User getUser();
}

ILog와 IUser를 만들고 IUser가 ILog를 상속받게 합니다.


public class Log extends RealmObject implements ILog{
public long createdTs;
public long updatedTs;

@Override
public Log getLog() {
return this;
}
}
public class User extends RealmObject implements IUser{
public Log log;
public String name;
public int age;
public String email;

@Override
public Log getLog() {
return log;
}

@Override
public User getUser() {
return this;
}
}

그리고 Log가 ILog를 실체화하고 User가 IUser를 실체화합니다.


이렇게 되면 Interface를 이용해서 다형성을 유지 할 수 있게 됩니다.


그리고 객체에 접근하기 위해서 getter를 선언해줍니다.


3. 동일한 primary key주기


Realm에서 객체를 update하기 위해서는 primary key가 선언되어 있어야 합니다.


이렇게 했을때 has-a관계에 있는 모델들이 동일한 primary key를 가지고 있어야만 is-a관계처럼 동일한 디비를 가질수 있게 됩니다.


public class Log extends RealmObject implements ILog {
public long createdTs;
public long updatedTs;
@PrimaryKey
private long logId;

public Log(long logId) {
this.logId = logId;
}

public Log() { }

public long getLogId() {
return logId;
}

@Override
public Log getLog() {
return this;
}
}
public class User extends RealmObject implements IUser {
public Log log;
public String name;
public int age;
public String email;
@PrimaryKey
private long logId;

public User(long logId) {
this.logId = logId;
log = new Log(logId);
}

public User() { }

public long getLogId() {
return logId;
}

@Override
public Log getLog() {
return log;
}

@Override
public User getUser() {
return this;
}
}

이렇게 하면 logId는 생성자를 통해서만 set할 수 있고 User와 Log가 동일한 logId를 가질 수 있습니다.


기본 생성자는 Realm에서 사용하기 떄문에 선언해줘야합니다.


4. auto increment 만들기


Realm realm = Realm.getDefaultInstance();
Number number = realm.where(Log.class).max("logId");
long logId = number == null ? 0 : number.longValue() + 1;
User user = new User(logId);

이렇게 하게 되면 Log의 마지막 logId값 보다 1큰 수를 logId로 가질 수 있게 됩니다.


5. 끝으로


이런식으로 기존 is-a관계를 has-a관계로 바꾸면서 primary key도 unique하게 가질 수 있는 구조를 만들었습니다.


하지만 이 방법이 정말 옳은지는 잘 모르겠습니다.


만약 이 포스팅을 보고 이 구조로 구현을 한다고 하시면 한번 더 고민해주셨으면 좋겠습니다.


여러분들의 많은 의견과 태클 감사하겠습니다.

728x90
반응형

+ Recent posts