3

次のテーブル構造を使用して、JPAで@OneToManyリレーションシップを作成しようとしています。

+----------------+
| CATALOG        |
+----------------+
| catalogId : PK |
| name           |
+----------------+
      |
+----------------+
| PRODUCT        |
+----------------+
| productId : PK |
| name           |
| catalogId : FK |
+----------------+

私はクラスを次のように定義しました

@Entity
public class Catalog {
    @Id
    @GeneratedValue
    long catalogId;

    @OneToMany(cascade = CascadeType.ALL, 
               orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinColumn(name = "catalogId", 
               nullable = false, insertable = true, updatable = true)
    Set<Product> products = new HashSet<>();

    String name;
}

@Entity
public class Product {
    @Id
    @GeneratedValue
    long productId;

    String name;
}

ただし、カタログオブジェクトを永続化しようとすると、EclipseLinkがcatalogId値を期待どおりに挿入せず、nullがあるというSQL制約違反が発生します。

また、製品側に@ManyToOneは必要ありません。

永続性コード:

final Catalog catalog = new Catalog();
catalog.name = text;
final Product p = new Product();
p.name = text;
catalog.products.add(p);
em.persist(catalog);

スタックトレース:

javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Column 'CATALOGID'  cannot accept a NULL value.
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1367)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1301)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:866)
    at net.trajano.maven_jee6.ws_mdb_ejb_web.TextMessages.putText(TextMessages.java:61)
4

3 に答える 3

7

あるテーブルProductの列の所有権を別のエンティティCatalogに付与すると、その列は、永続化Productの一部としてではなく、永続化Catalogの一部として更新および維持されます。フレームワークは製品を作成しますが、FK列は別のエンティティによって「所有」されているため、カタログが永続化されるときに生成される別の更新ステートメントがその列に入力されます。列をnull許容にするか、テーブルをマップするのと同じエンティティに列の所有権を設定する必要があります。

于 2012-06-15T05:22:57.623 に答える
1

@GeneratedValue注釈がないためだと思います(with Postgres)。私の経験から、、を使用するとPostgres、注釈は機能しません。とを指定する必要があり@SequenceGeneratorます@GeneratedValue。次に例を示します。



    @SequenceGenerator(name = "lan_generator", sequenceName = "lan_pkey_seq")
    @Id
    @GeneratedValue(generator = "lan_generator")
    @Column(name="id", unique=true, nullable=false)
    private Integer id;

他のデータベースを使用している場合は、自分のデータベースを処理してみてください。とにかく、givebリンクで、を使用しているときに可能な解決策がありますMySQL。おそらく、「メモリ内のダービーインスタンス」でも機能します。

MYSQL自動インクリメントフィールドにJPAアノテーションを付ける方法

于 2012-06-15T05:27:57.540 に答える
0

このような製品クラスを作成して、再試行してください-

@Entity
public class Product {
    @Id
    @GeneratedValue
    long productId;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "catalogId", updatable = false, insertable = false, nullable=false)  
    private Catalog  catalog ;

    String name;
}
于 2012-06-15T05:19:39.650 に答える