Генератор гибернации не будет вставлен с помощью уникального идентификатора
Я пытаюсь сопоставить сущность, используя аннотации Hibernate, чтобы при создании и сохранении записи (посредством каскада) автоматически генерировался идентификатор. При моей текущей настройке (или нескольких других, которые я пробовал) я получаю следующую ошибку:
...org.hibernate.exception.ConstraintViolationException:
could not insert: [com.gorkwobbler.shadowrun.karma.domain.AttributeScore]
...java.sql.SQLException:
Caused by: java.sql.SQLException: Cannot insert the value NULL into column 'id', table 'KARMA_DEV.dbo.Character'; column does not allow nulls. INSERT fails.
Я вижу, что выдается следующая инструкция вставки:
Hibernate: insert into character (version, alias, firstName, lastName) values (?, ?, ?, ?)
Понятно, что это неправильно, здесь нет параметра "id".
Моя схема таблицы, на данный момент, просто:
Character(
id uniqueidentifier, --primary key
alias varchar(max),
firstName varchar(max),
lastName varchar(max),
version int --for hibernate
)
Я использую SQL Server 2008 R2, экспресс-издание.
Мои аннотации разделены между сопоставленным суперклассом DomainEntity и конкретным классом KarmaCharacter:
@MappedSuperclass
public abstract class DomainEntity implements Serializable /* Needed for HOM retainUnsaved */ {
private static final long serialVersionUID = 1L;
private String id;
private Integer version;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Generated(value=GenerationTime.INSERT)
//@GeneratedValue(generator="hibernate-uuid.hex")
//@GenericGenerator(name="hibernate-uuid.hex", strategy="org.hibernate.id.UUIDHexGenerator", parameters=@Parameter(name="separator", value="-"))
@AccessType(value="field")
public String getId() {
return id;
}
@Version
@AccessType(value="field")
public Integer getVersion() {
return version;
}
}
@SuppressWarnings("serial")
@Entity
@Table(name="character")
public class KarmaCharacter extends DomainEntity {
private String alias;
private String lastName;
private String firstName;
private SortedSet<AttributeScore> attributeScores;
public KarmaCharacter() {
//default constructor
}
@Column
@AccessType(value="field")
public String getAlias() {
return alias;
}
@Column
@AccessType(value="field")
public String getFirstName() {
return firstName;
}
@Column
@AccessType(value="field")
public String getLastName() {
return lastName;
}
//...omitted some transient code and a collection property for brevity
public void setAlias(String alias) {
this.alias = alias;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Если бы кто-то мог сказать мне правильный способ создания уникальных идентификаторов типа идентификатора с помощью спящего режима в SQL Server и обеспечить их правильное сохранение, это было бы очень полезно.
1 ответ
Я вижу, как выдается следующий оператор вставки (...). Понятно, что это неправильно, здесь нет параметра "id".
Действительно, при использовании uniqueidentifier
Тип SQL Server, Hibernate должен использовать newid()
, Но ваши текущие аннотации не говорят об этом. Я думаю, что вам нужно guid
генератор здесь:
@Id
@GenericGenerator(name = "generator", strategy = "guid", parameters = {})
@GeneratedValue(generator = "generator")
public String getId() {
return id;
}
Некоторые дополнительные замечания:
- Тип столбца GUID действительно предназначен для хранения GUID, сгенерированного алгоритмом Microsoft, вы не можете использовать алгоритм UUID Hibernate.
- Вам не нужно
Generated
аннотация наId
Просто удали это. - Мне также интересно, почему вы "портите" остроумие
AccessType
Я бы просто удалил их. - Я бы на самом деле не использовал GUID (см. Эту статью), но это уже другая история.