3

我想映射一個實體使用Hibernate Annotations,以便當創建和保存(通過級聯)記錄時,會自動生成一個ID。隨着我的當前設置(或其他一些我已經試過)我得到以下錯誤:休眠生成器不會插入uniqueidentifier

...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,Express版本。

我的註釋映射超,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型ID與Hibernate的SQL Server中的正確的方式,和讓他們得到妥善保存,這將非常感激。

回答

7

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

事實上,使用uniqueidentifier SQL服務器類型時,Hibernate必須使用newid()。但是你目前的註釋並沒有告訴它這樣做。我認爲你需要的guid發電機在這裏:

@Id 
@GenericGenerator(name = "generator", strategy = "guid", parameters = {}) 
@GeneratedValue(generator = "generator") 
public String getId() { 
    return id; 
} 

一些補充說明:

  • 的GUID列類型是真正的意思持有微軟的算法生成一個GUID,你不能使用Hibernate的UUID算法。
  • 您不需要Id上的Generated註釋,只需將其刪除即可。
  • 我也想知道你爲什麼「搞砸」智慧AccessType,我只是刪除它們。
  • 我實際上不會使用GUID(請參閱this article),但這是另一回事。
+0

謝謝!這正是我所希望的,我不知道如何讓hibernate使用newid()。 – RMorrisey 2010-06-20 19:26:37

+0

我使用@AccessType,因爲沒有setId()方法。我這樣做是因爲我的應用程序代碼沒有理由更改ID。 – RMorrisey 2010-06-20 19:27:37

+0

@Rororrisey:我明白了(但是我會讓setter受到保護) – 2010-06-20 19:48:50