Генератор гибернации не будет вставлен с помощью уникального идентификатора

Я пытаюсь сопоставить сущность, используя аннотации 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 (см. Эту статью), но это уже другая история.
Другие вопросы по тегам