3

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 で休止状態を使用して一意の識別子タイプの ID を生成し、それらを適切に保存する正しい方法を教えてくれれば、大歓迎です。

4

1 に答える 1

7

次の挿入ステートメントが発行されていることがわかります (...)。明らかにこれは間違っています。「id」パラメータはありません。

実際、uniqueidentifierSQL Server タイプを使用する場合、Hibernate は を使用する必要があります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 は使用しませんが (この記事を参照)、これは別の話です。
于 2010-06-20T14:59:50.097 に答える