Как установить обратную ссылку из @EmbeddedId в JPA - PullRequest
5 голосов
/ 08 января 2011

Кто-нибудь знает, возможно ли установить обратную ссылку из JPA @EmbeddedId.

Так, например, существует сущность формы

@Entity
public class Entity1 {
    @Id
    @GeneratedValue
    private String identifier;

    private Entity1 relationToEntity1;
    //Left out the getters and setters for simplicity
}

и вторая сущность со сложным встроенным идентификатором.Одна часть этого второго объекта является ссылкой на его родительский объект.Вот так:

@Entity
public class Entity2 {
    @EmbeddedId private Entity2Identifier id;
    //Left out the getters and setters for simplicity.
}

@Embedabble
public class Entity2Identifier {
    private String firstPartOfIdentifier;
    private Entity1 parent;
    //Left out the getters and setters for simplicity.
}

Когда я пытаюсь сохранить такую ​​конструкцию через JPA (реализация - EclipseLink) в базе данных, я получаю несколько исключений вида:

</p> <pre><code>Exception [EclipseLink-93] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT): org.eclipse.persistence.exceptions.DescriptorException Exception Description: The table [ENTITY1] is not present in this descriptor. Descriptor: RelationalDescriptor(test.Entity2 --> [DatabaseTable(ENTITY2)])

Кто-то сталкивался с такой проблемой и имеет решение?

Ответы [ 2 ]

4 голосов
/ 14 января 2011

То, что вы ищете, является производным идентификатором.Если вы используете JPA 2.0, то будет работать следующее.Вы действительно не хотите, чтобы весь Родитель был частью ПК, просто ПК родителя.

@Entity
public class Entity1 {
    @EmbeddedId
    private ParentId identifier;

    @OneToOne(mappedBy="relationToEntity1")
    private Entity2 relationToEntity2;

    //Left out the getters and setters for simplicity
}

@Entity
public class Entity2 {
    @EmbeddedId private Entity2Identifier id;
    //Left out the getters and setters for simplicity.

    @MapsId("parentId")
    @OneToOne
    private Entity1 parent;

}

@Embedabble
public class Entity2Identifier {
    private String firstPartOfIdentifier;
    private ParentId parentId;
    //Left out the getters and setters for simplicity.
}
1 голос
/ 08 января 2011

Аннотация @EmbeddedId не допускает отношений в классе составных идентификаторов. Из EmbeddedId JavaDoc :

Отображения отношений, определенные во встроенном классе идентификаторов, не поддерживаются.

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

Если вы просто ищете простой способ установить двунаправленные отношения, вы можете сделать это с помощью аннотации @OneToOne и атрибута mappedBy:

@Entity
public class Entity1 {
    @Id
    @GeneratedValue
    private String identifier;

    @OneToOne(mappedBy="relationToEntity1")
    private Entity2 relationToEntity2;
    ...
}

@Entity
public class Entity2 {

    @OneToOne
    private Entity1 relationToEntity1;
    ...
}

С этим набором аннотаций поставщик JPA будет правильно обрабатывать Entity1.relationToEntity2 и Entity2.relationToEntity1 как двунаправленные отношения. Вы также можете переопределить стандартное поведение каскада (нет), а также стандартное поведение удаления сирот (нет). Подробнее см. JavaDoc .

...