代码之家  ›  专栏  ›  技术社区  ›  RMorrisey

休眠生成器无法插入唯一标识符

  •  3
  • RMorrisey  · 技术社区  · 15 年前

        ...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 (?, ?, ?, ?)
    

    目前,我的表模式很简单:

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

    我使用的是SQLServer2008R2速成版。

    我的注释在映射的超类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;
        }
    }
    

    1 回复  |  直到 14 年前
        1
  •  7
  •   Pascal Thivent    15 年前

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

    事实上,当使用 uniqueidentifier newid() . 但您当前的注释并没有告诉它这样做。我想你需要 guid 此处为发电机:

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

    一些补充说明:

    • GUID列类型实际上是用来保存由Microsoft算法生成的GUID,不能使用Hibernate的UUID算法。
    • 你不需要 Generated Id ,把它取下来。
    • 我也想知道你为什么要“捣乱”机智 AccessType ,我就把它们取下来。
    • 我实际上不会使用GUID(请参阅 this article )但这是另一个故事。