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