Ошибка JPA: объект не имеет атрибута первичного ключа, определенного
Я использую JPA в своем приложении. В одной из таблиц я не использовал первичный ключ (я знаю его плохой дизайн).
Теперь созданный объект имеет значение, указанное ниже:
@Entity
@Table(name="INTI_SCHEME_TOKEN")
public class IntiSchemeToken implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name="CREATED_BY")
private String createdBy;
@Temporal( TemporalType.DATE)
@Column(name="CREATED_ON")
private Date createdOn;
@Column(name="SCH_ID")
private BigDecimal schId;
@Column(name="TOKEN_ID")
private BigDecimal tokenId;
public IntiSchemeToken() {
}
public String getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getCreatedOn() {
return this.createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public BigDecimal getSchId() {
return this.schId;
}
public void setSchId(BigDecimal schId) {
this.schId = schId;
}
public BigDecimal getTokenId() {
return this.tokenId;
}
public void setTokenId(BigDecimal tokenId) {
this.tokenId = tokenId;
}
}
Здесь В моем проекте Eclipse IDE показывает маркер ERROR (RED color cross) в этом классе, а ошибка " Сущность не имеет атрибута первичного ключа, определенного".
Может ли кто-нибудь сказать мне, как создать объект без первичного ключа?
Спасибо.
Ответы
Ответ 1
Вы не можете. Сущность ДОЛЖНА иметь уникальный, неизменяемый идентификатор. Он не должен быть определен как первичный ключ в базе данных, но поле или набор полей должны однозначно идентифицировать строку, и ее значение может не измениться.
Итак, если одно поле в вашей сущности или один набор полей в вашей сущности удовлетворяет этим критериям, сделайте (или их) идентификатор объекта. Например, если пользователь не может создать два экземпляра за один день, вы можете сделать [createdOn, createdBy] идентификатором объекта.
Конечно, это плохое решение, и вы должны действительно изменить свою схему и добавить в объект автоматически генерируемый идентификатор с одним столбцом.
Ответ 2
Если ваш первичный ключ (PK) является управляемым суперклассом, который наследуется в классе сущности, вам нужно будет включить отображаемое имя суперкласса в файле persistence.xml.
Посмотрите на отчет об ошибке:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=361042
Ответ 3
Если вам нужно определить класс без первичного ключа, вы должны пометить этот класс как класс Embeddable. В противном случае вы должны указать первичный ключ для всех объектов, которые вы определяете.
Ответ 4
Вы можете отключить (изменить) валидацию, которая была добавлена.
Перейдите к настройкам рабочей области "Сохранение Java" → JPA- > "Ошибки/предупреждения", следующий "Тип" и изменение "Объект не имеет первичного ключа" в "Предупреждение".
Ответ 5
В дополнение к http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#No_Primary_Key вы можете использовать некоторые встроенные столбцы, такие как ROWID
в Oracle:
но с осторожностью:
Структуры сущностей не работают для всех типов данных (например, статистические данные, которые использовались для анализа не для запросов).
Ответ 6
Другое решение без Hibernate
Если
- у вас нет ПК на столе
- существует логическая комбинация столбцов, которые могут быть PK (не обязательно, если вы можете использовать какой-то rowid)
- но некоторые из столбцов являются NULLable, поэтому вы действительно не можете создавать ПК из-за ограничения БД
- и вы не можете изменить структуру таблицы (разделили бы команды insert/select без явно перечисленных столбцов в устаревшем коде)
тогда вы можете попробовать следующий трюк
- создать представление в базе данных с виртуальным столбцом, имеющим значение столбцов конкатенированных логических ключей ('A =' || a || 'B =' || 'C =' c..) или rowid
- создайте свой класс сущности JPA в этом представлении
- отметьте виртуальный столбец аннотацией @Id
Что это. Также возможно обновление/удаление операций с данными (не вставка), но я бы не использовал их, если столбец виртуального ключа не сделан из rowid (чтобы избежать полных поисков сканирования по таблице DB)
P.S. Эта же идея частично описана в связанном вопросе.
Ответ 7
Вам нужно создать первичный ключ. Если не найдено ни одного подходящего поля, тогда создайте идентификатор автоматического увеличения.
CREATE TABLE fin_home_loan (
ID int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (ID));