2017-12-20 24 views
1

データベースにエンティティを作成し、外部キーなしで外部キーを更新しようとしています。hibernate:外部キーを持たないエンティティを保存するときの例外

@Entity 
public class Business { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int businessId; 

    @Column 
    private String businessName; 

    @ManyToOne() 
    @JoinColumn(name="billTypeId", nullable=true) 
    @NotFound(action=NotFoundAction.IGNORE) 
    private BillType billType; 

    // getters and setters 
} 

billType属性がNULL値を持って、私は次の例外になっています:私は、ビジネスオブジェクトを永続化するとbillTypeIdフィールドにゼロ値を持つことができますどのように

Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn:54) 
Column 'billTypeId' cannot be null 
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:152) 
at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:118) 

、billTypeメンバーをnullです

+0

あなたのコードは、データベースによって強制される制約と矛盾します。 NotFoundアノテーション(一貫性のないデータベースを扱うためのハック)を削除し、エンティティを保存する前に請求書タイプを設定するだけです。 –

+0

データベースによって強制される制約はありません。 私はbillTypeを設定して動作させることができます。しかし、まずはBillTypeを使わないでBusinessオブジェクトを保存し、後でそれを設定する必要があります。私の質問はどうですか? –

+1

それは例外ではありません: 'SQLIntegrityConstraintViolationException'です。あなたはほとんど制約が違反されたと思うでしょう。 – Kayaman

答えて

1

一般的に私はこのアプローチを再考し、データベースのbillTypeId列のNULL値を許可することを推奨します。これは標準的な動作です。また、0の値は、今後指定する任意の外部キー制約によって参照されると見なされます(ID)。あなたは別のアプローチを試してみたい場合は

はまだ

1つのオプションは、COMMITまたはMANUALAUTO(デフォルト)からフラッシュモードを変更すると、実際にデータベースに何かをフラッシュする前に、完全なエンティティツリーを構築することです。 (AUTOSELECT前にセッションの変更をチェックし、いずれかが存在する場合、変更をデータベースにフラッシュされます。これは、あなたが最新のデータを読んでいることを保証するだけでなく、パフォーマンスを殺す。)

さらにHibernateは

  • を提供唯一のNOT NULL列値(doc)だけでどの値ではない列に対してUPDATE文を生成するために、休止状態をアドバイスします
  • @DynamicUpdate注釈のためINSERT文を生成するために、休止状態をアドバイスします@DynamicInsert注釈変更されました(doc

私はこのようなアプローチを慎重に使用することをお勧めします。

また、insertableupdatableアトリビュートを@JoinColumn注釈(doc)と指定することもできます。あなたがリンクを使わずにレコードを挿入し、それを後で更新する場合は、insertable=falseが役に立ちます。

+0

ありがとうございます、@DynamicInsert実際に私の問題を解決しました –

+0

あなたの問題を解決した場合は、投票してください。 –

+0

私は答えを受け入れましたが、私はこのサイトのノブなので、まだ投票をカウントしません。 –

関連する問題