3

Я пытаюсь отобразить объект с использованием аннотаций 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", [email protected](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; 
    } 
} 

Если кто-то может сказать мне правильный путь для создания uniqueidentifer-типа идентификаторов с Hibernate в SQL Server, и чтобы они были сохранены должным образом, это было бы очень признательно.

ответ

7

I can see the following insert statement being issued (...). Clearly this is wrong, there is no "id" parameter.

Действительно, при использовании типа 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, просто удалите его.
  • Я также удивляюсь, почему вы «messing» wit AccessType, я бы просто удалил их.
  • Я бы не использовал GUID (см. this article), но это еще одна история.
+0

Спасибо! Это именно то, на что я надеялся, я не знал, как использовать hibernate для использования newid(). – RMorrisey

+0

Я использую @AccessType, потому что нет метода setId(). Я сделал это так, потому что нет причин для изменения кода моего приложения. – RMorrisey

+0

@RMorrisey: Я вижу (но я бы сделал сеттер защищенным тогда) –