JPA сущность без идентификатора - PullRequest
43 голосов
/ 29 сентября 2010

У меня есть база данных со следующей структурой:

CREATE TABLE entity (
    id SERIAL,
    name VARCHAR(255),
    PRIMARY KEY (id)
);

CREATE TABLE entity_property (
    entity_id SERIAL,
    name VARCHAR(255),
    value TEXT
);

Когда я пытаюсь создать класс EntityProperty

@Entity
@Table(name="entity_property")
public class EntityProperty {

    private String name;
    private String value;

    @Column(name="name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Column(name="value", nullable=true, length=255)
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

, я получаю следующее исключение:

org.hibernate.AnnotationException: No identifier specified for entity: package.EntityProperty

Я знаю, что сущности JPA должны иметь первичный ключ, но я не могу изменить схему базы данных по причинам, которые находятся вне моего контроля.Можно ли создать JPA (Hibernate) сущности, которые будут работать со схемой базы данных, как это?

Ответы [ 5 ]

38 голосов
/ 29 сентября 2010

Полагаю, у вашего entity_property есть составной ключ (entity_id, name), где entity_id - это внешний ключ для entity.Если это так, вы можете отобразить его следующим образом:

@Embeddable
public class EntityPropertyPK {
    @Column(name = "name")
    private String name;

    @ManyToOne
    @JoinColumn(name = "entity_id")
    private Entity entity;

    ...
}

@Entity 
@Table(name="entity_property") 
public class EntityProperty { 
    @EmbeddedId
    private EntityPropertyPK id;

    @Column(name = "value")
    private String value; 

    ...
}
25 голосов
/ 29 сентября 2010

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

Точнее, для объекта JPA должно быть определено Id. Но JPA Id не обязательно должен отображаться на первичный ключ таблицы (и JPA может каким-то образом иметь дело с таблицей без первичного ключа или ограничения уникальности).

Можно ли создать JPA (Hibernate) сущности, которые будут работать с такой структурой базы данных?

Если у вас есть столбец или набор столбцов в таблице, которые имеют уникальное значение, вы можете использовать этот уникальный набор столбцов как Id в JPA.

Если в вашей таблице вообще нет уникальных столбцов, вы можете использовать все столбцы как Id.

И если у вашей таблицы есть какой-то идентификатор, а у вашей сущности нет, сделайте его Embeddable.

18 голосов
/ 08 июля 2011

См. Книгу Java Persistence : Идентичность и последовательность

Соответствующей частью вашего вопроса является раздел Нет первичного ключа :

Иногда ваш объект или таблица не имеют первичного ключа.Лучшее решение в этом случае - добавить сгенерированный идентификатор к объекту и таблице.Если у вас нет этой опции, иногда в таблице есть столбец или набор столбцов, которые составляют уникальное значение.Вы можете использовать этот уникальный набор столбцов в качестве идентификатора в JPA.JPA Id не всегда должен соответствовать ограничению первичного ключа таблицы базы данных, а также не требуется первичный ключ или ограничение уникальности.

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

Если у вашего объекта нет идентификатора, но его 'таблица делает, это нормально.Сделайте объект Embeddable объектом, встраиваемые объекты не имеют идентификаторов.Вам понадобится Entity, который содержит Embeddable, чтобы сохранить его и запросить его.

3 голосов
/ 29 сентября 2010

Полагаю, вы можете использовать @CollectionOfElements (для hibernate / jpa 1) / @ElementCollection (jpa 2), чтобы отобразить коллекцию "свойств сущностей" в List in entity.

Вы можете создать тип EntityProperty и аннотировать его с помощью @Embeddable

1 голос
/ 29 сентября 2010

Если между сущностью и entity_property существует однозначное соответствие, вы можете использовать entity_id в качестве идентификатора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...