休眠生成器不会插入唯一标识符

发布于 2024-09-06 07:23:52 字数 2733 浏览 8 评论 0原文

我正在尝试使用 Hibernate Annotations 映射一个实体,以便在创建并保存记录(通过级联)时,会自动生成一个 ID。使用我当前的设置(或我尝试过的其他一些设置),我收到以下错误:

    ...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", 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 中使用 hibernate 生成 uniqueidentifer 类型 ID 的正确方法,并让它们正确保存,那就太好了赞赏。

I'm trying to map an entity using Hibernate Annotations, so that when a record is created and saved (via cascade), an ID is automatically generated. With my current setup (or a few others I've tried) I get the following error:

    ...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.

I can see the following insert statement being issued:

Hibernate: insert into character (version, alias, firstName, lastName) values (?, ?, ?, ?)

Clearly this is wrong, there is no "id" parameter.

My table schema, for now, is simply:

Character(
 id uniqueidentifier, --primary key
 alias varchar(max),
 firstName varchar(max),
 lastName varchar(max),
 version int --for hibernate
)

I am using SQL Server 2008 R2, Express edition.

My annotations are split between a mapped superclass, DomainEntity, and a concrete class, 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;
    }
}

If someone could tell me the right way to generate uniqueidentifer-type ID's with hibernate in SQL Server, and get them to be saved properly, it would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

記憶穿過時間隧道 2024-09-13 07:23:52

我可以看到正在发出以下插入语句(...)。显然这是错误的,没有“id”参数。

事实上,当使用uniqueidentifier SQL Server 类型时,Hibernate 必须使用newid()。但您当前的注释并没有告诉它这样做。我认为你需要 guid 生成器:

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

一些附加说明:

  • GUID 列类型实际上是为了保存由 Microsoft 算法生成的 GUID,您不能使用 Hibernate 的 UUID 算法。
  • 您不需要在 Id 上使用 Generate 注释,只需将其删除即可。
  • 我还想知道为什么你要“搞乱”AccessType,我只想删除它们。
  • 我实际上不会使用 GUID(请参阅 这篇文章)但这是另一个故事了。

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

Indeed, when using the uniqueidentifier SQL Server type, Hibernate has to use newid(). But your current annotations are not telling it to do so. I think you need the guid generator here:

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

Some additional remarks:

  • The GUID column type is really meant to hold a GUID generated by Microsoft's algorithm, you can't use Hibernate's UUID algorithm.
  • You don't need the Generated annotation on an Id, just remove it.
  • I also wonder why you are "messing" wit AccessType, I would just remove them.
  • I would actually not use a GUID (see this article) but this is another story.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文