2015-02-16 4 views
3

У меня есть два класса сущностей A и B. Для A существует только один экземпляр класса B. Через жизненный цикл приложения мне нужно создать новый insta для B для A. Но для журнала истории мне нужно для хранения предыдущего экземпляра B со ссылками на этот экземпляр A. Так что я создал следующее отображение:JPA cross unireirectional OneToOne

@Entity 
class A { 
    @OneToOne 
    @JoinColumn(name="B_ID") 
    B b; 
} 

@Entity 
class B { 
    @OneToOne 
    @JoinColumn(name="A_ID") 
    A a; 
} 
/////// 
CREATE TABLE A_TABLE (ID uuid, B_ID uuid, FOREIGN KEY (B_ID) REFERENCES B_TABLE(ID)); 
CREATE TABLE B_TABLE (ID uuid, A_ID uuid, FOREIGN KEY (A_ID) REFERENCES A_TABLE(ID)); 

У меня уже есть некоторые правильные данные в моих таблицах, но каждый раз, когда я пытаюсь получить любой экземпляр класса А, поле Ь нуль. Итак, что я делаю неправильно?

UPD_0 Хорошо, вот что я действительно имеем дело с:

@MappedSuperclass 
public abstract class BaseUuidEntity { 
    @Id 
    @Column(name = "ID") 
    @Persistent 
    protected UUID id; 
} 

@MappedSuperclass 
public class StandartEntity extends BaseUuidEntity { ... } 
@MappedSuperclass 
public abstract class AbstractEntity extends BaseUuidEntity { ... } 
@Entity(name = "CardEntity") 
@Table(name = "TBL_CARD") 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorColumn(name = "CARD_TYPE", discriminatorType = DiscriminatorType.INTEGER) 
@DiscriminatorValue("0") 
public class CardEntity extends AbstractEntity { ... } 

@Entity("aEntity") 
@DiscriminatorValue("1") 
@Table(name = "A_TABLE") 
class A extends CardEntity { 
    @OneToOne 
    @JoinColumn(name="B_ID") 
    B b; 
    public String getBName() { 
     return b.getName(); // NullPointerException 
    } 
} 
@Entity("bEntity") 
@Table(name = "B_TABLE") 
class B extends StandartEntity { 
    @Column(name="name") 
    String name; 
    public String getName() { 
     return this.name; 
    } 
} 

-- A_TABLE (ID, B_ID) 
'41a2647d-2ef6-f507-92ee-bff0f784b6f3', '5d3c66da-b377-11e4-bc9c-1008b124eacf' 
-- B_TABLE (ID, A_TABLE, NAME) 
'5d3c66da-b377-11e4-bc9c-1008b124eacf', '41a2647d-2ef6-f507-92ee-bff0f784b6f3', 'Some text' 

Я получаю все А объекты (в моем случае - это один)

select e from aEntity e 

и пытается чтобы получить имя объекта b в каждом из них, но получая nullpointer, причина b равна null;

+0

Как вы получаете экземпляр класса A? Можете ли вы показать свой код? –

+0

Просто простой запрос по Id: Запрос q = em.createQuery («выберите e из my.package.A e, где e.id =: id"); q.setParameter ("id", needed_uid); q.getSingleResult(); –

+0

Этот код выглядит хорошо, поэтому проблема должна быть с чем-то, что вы не показываете. У вас есть аннотации @Id в ваших сущностях? Можете ли вы показать им? –

ответ

0

Я не уверен, если это будет делать какие-либо различия, но попробуйте изменить код в getBName() использовать сорбент вместо того, чтобы непосредственно ссылки на экземпляр переменной b:

public String getBName() { 
    return getB().getName(); 
} 

вместо:

public String getBName() { 
    return b.getName(); // NullPointerException 
} 

Я подозреваю, что это может быть проблемой, поскольку реализации JPA создают прокси для объектов, которые обычно являются подклассами ваших объектов, и эти прокси переопределяют ваши получатели и сеттеры. Поэтому, если вы не используете геттер, может случиться так, что переменная экземпляра не будет правильно инициализирована.

+0

Nope, извините, все тот же null. Но, действительно, вы даете мне Идею, поэтому я попытался установить @Access (AccessType.FIELD) для поля Ab и получил это исключение в сборке: Поле «my.package.Ab» с «явным доступом к полям» не является совместимый с «неявным доступом к полям», используемый его объявляющим классом. Я не знаю, может, это даст вам другую идею. –

+0

Я решил это! Фактически, да, ты правдивый о реализации. В моем случае это была «особенность» структуры - мне нужно было добавить эту фелду, которая используется на моем экране. Спасибо, мужик! –

-1

вам необходимо сопоставитьBy anotation: http://en.wikibooks.org/wiki/Java_Persistence/OneToOne , чтобы сообщить java, который отвечает за эти отношения и когда хранится «foreign'id». Вам также нужен внешний ключ только в одном из объектов не обоих!

+0

Но мне нужны оба! Мне нужно сохранить предыдущие экземпляры B для некоторого экземпляра класса A. И мне нужно определить рабочий экземпляр B для экземпляра A. И mappedBy устанавливает двунаправленное отношение, но, как я писал, мне нужны два однонаправленных отношения. –

+0

@Zielu Он не хочет делать двунаправленное отношение, ему нужны два отдельных однонаправленных отношения. –