3

私はarquillianでコンテナ内テストを実行しています。import.sqlデプロイメントにを追加して、データベースに事前入力しています。テスト中に、さらにいくつかのエンティティを作成したいと思います。

残念ながら、これは:で失敗しPersistenceExceptionます

javax.persistence.PersistenceException:org.hibernate.exception.ConstraintViolationException:一意のインデックスまたは主キー違反: "PRIMARY_KEY_BE ON PUBLIC.KVS_MIPO_DOWNLOAD(ID)"

DBに事前入力しない場合、または新しいエンティティを永続化しない場合、すべてがスムーズに実行されます。

idは唯一の一意のフィールドであるため、シーケンスを使用したid生成である必要があると強く思います。

@Entity
@Table(name = "KVS_MIPO_DOWNLOAD")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class DownloadResource implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Integer id;

このエンティティは、一意の属性を追加しない別の具象エンティティのスーパークラスです。

両方の可能性に対応できるようにするために何ができるでしょうか?手動で挿入し、生成されたIDを使用しますか?

ありがとうございました

JBoss7.1.1のHibernate4.0.1でJPA2を使用しています。データベースはSybaseASE15です。

編集:これまでに見つけた回避策の1つは、手動で追加したエンティティのIDを、衝突を回避するのに十分な高さに設定することです。しかし、これは本番環境には十分ではありません。データベースへの書き込みアクセス権を持っている従業員が多すぎるため、手動で追加したくなる場合があります。この場合、アプリケーションが死んだり爆発したりしないように十分に堅牢であることが望ましいです。

4

3 に答える 3

3

手動IDには負の値を使用してください。Hibernateは負の値を生成するべきではありません。

必要に応じて、特定の範囲をスキップする独自のIDジェネレーターを使用します(または、7で割り切れる数をスキップします。そのようなスキームもあります)。

サンプルIDジェネレーター:

import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;

public class MyGenerator implements IdentifierGenerator {

    public Serializable generate(SessionImplementor session, Object object)
            throws HibernateException {
        return 1; // TODO: Your scheme to create an Integer;
    }
}

この注釈を使用するには、次のようにします。

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "myid")
@GenericGenerator(name = "myid", strategy = "com.x.y.z.MyDGenerator")
public int getId() {
    return _id;
}
于 2013-01-18T18:36:30.193 に答える
1

UUIDをIDとして使用することも、シーケンスとして使用することもできます。手動で追加されたデータは、シーケンスを参照することもできます。

于 2013-01-18T18:49:00.457 に答える
1

Fastnateを使用する場合import.sqlは、JPAモデルとデータベースに十分な正しいIDでを作成できます。

たとえば、次の方法でエンティティを作成できます。

EntitySqlGenerator generator = new EntitySqlGenerator(new FileWriter("import.sql"));
List<DownloadResource> resources = createDownloadResources();
generator.write(resources);

を作成するためのオプションは他にもいくつかありますがimport.sql、最初はそれで十分です。

Fastnateは現在Sybaseを特別にサポートしていませんが、ほとんどの場合、デフォルトの方言(H2)も同様に機能します。

于 2014-12-17T20:34:53.497 に答える