7

Hibernate は次の例外をスローしています。

Caused by: java.sql.SQLException: Field 'catVerb_id' doesn't have a default value

問題は AUTO_INCREMENT ステートメントを持たない私の PK にあると人々は言いますが、私のデータベースでこれを実行したことがわかり、問題は続いています。そこで、クラスとデータベースの実装を持ち込みました。

私の問題はテストクラスにあると思います...誰かがこれをテストする方法を教えてくれますか?

(はい、いくつかの単語はポルトガル語ですが、理解できます)。

カテゴリーVerbete

@Entity
@Table(name="verbete_categoria")
public class CategoriaVerbete implements Serializable{
    private long id;
    private String nome;
    private String descricao;
    private int serie;
    private Set<Verbete> verbetes = new HashSet<Verbete>();
    private Set<SignificadosVerbete> significados = new HashSet<SignificadosVerbete>();

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="catVerb_id")
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }

    ...

    @OneToMany(cascade = {CascadeType.ALL})
    @JoinColumn(name="catVerb_id", nullable = true) 
    public Set<Verbete> getVerbetes() {
        return verbetes;
    }
    public void setVerbetes(Set<Verbete> verbetes) {
        this.verbetes = verbetes;
    }

    @OneToMany(cascade = {CascadeType.ALL})
    @JoinColumn(name="catVerb_id", nullable = true)
    public Set<SignificadosVerbete> getSignificados() {
        return significados;
    }
    public void setSignificados(Set<SignificadosVerbete> significados) {
        this.significados = significados;
    }

}

詳細

@Entity
@Table(name="verbete")
public class Verbete implements Serializable{
   ...

    @ManyToOne
    @JoinColumn(name="catVerb_id", insertable = false, updatable = false)
    public CategoriaVerbete getCategoria() {
        return categoria;
    }
    public void setCategoria(CategoriaVerbete categoria) {
        this.categoria = categoria;
    }

    ...
}

重要事項Verbete

@Entity
@Table(name="verbete_significados")
public class SignificadosVerbete {
    ... 

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="catVerb_id", insertable = false, updatable = false)
    public CategoriaVerbete getCategoria() {
        return categoria;
    }
    public void setCategoria(CategoriaVerbete categoria) {
        this.categoria = categoria;
    }

   ...

}

データベースで...

CREATE TABLE verbete_categoria (
catVerb_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
catVerb_nome VARCHAR(100) UNIQUE,
catVerb_descricao MEDIUMTEXT,
catVerb_serie INT NOT NULL
);

どんな助けでも大歓迎です、ありがとう。

更新 - 問題は解決しました

うーん、勝利のサウンドトラックを期待していましたが、大丈夫です...

このリンクの内容に従いました:

https://www.ibm.com/developerworks/community/blogs/fd26864d-cb41-49cf-b719-d89c6b072893/entry/como_criar_relacionamento_onetomany_com_hibernate?lang=en

そのリンクにあるものはHibernateのドキュメントでは推奨されていないことを読みましたが、推奨事項に従おうとしてエラーを処理するのに1週間かかりました。だから、これが他の人に役立つことを願っています。

そして、すべての答えに感謝します。

4

4 に答える 4

1

java.sql.SQLException: フィールド 'xxxx' にデフォルト値がありません

(別名。間接的な Fetch.LAZY 負荷の問題)

今日、この問題に遭遇しました。

私の状況ではいくつかの問題であることが判明しました。

私が最初に修正しなければならないことがわかったのは、問題のリストを遅延ロードする必要があるということでした。そして、LAZY LOADED とは、データベースが「セッション中」のときにデータベースからアクセスする必要があることを意味します。ここで、Fetch.LAZY を扱うときにしなければならないことがわかった小さなトリックがあります。たとえば、コンテナにロードするときに、参照先のオブジェクトのメソッドを (一見不必要に) 呼び出す必要があります。セッションオブジェクト内であっても、参照を返すだけでは十分ではありません。

たとえば、次のように言うだけではありません。

public List<Apple> getApples(Kid kid) throws KidNotFoundException 
{
    log.info("getApples (service) called"); 
    kid = get(kid);
    List<Apple> list = kid.getApples();
    return list;
}

一見取るに足らないステップをもう 1 つ追加する必要があります。JPA の Lazy Load メカニズムをトリガーするには、参照されたオブジェクト自体でメソッドを呼び出す必要があります (これは、@Stateless タグを介して直接または暗黙的に行われるかどうかにかかわらず、JPA トランザクション内でのみ機能します)。そうするまで、JPA は不要なオブジェクトをメモリに読み込まないように最善を尽くします (別名、 Fetch.LAZY の背後にある全体的な考え方)。

したがって、この場合、取得した ( Fetch.LAZY 指定 ) オブジェクト 'list' でメソッドを呼び出します。

 list.size();

オブジェクトの任意のメソッドを呼び出して、JPA がオブジェクト (または複数のオブジェクト) をロードするようにトリガーできます。一見不必要な kid.getName(); の呼び出し プロの視点から。Fetch.LAZY に関する優れたチュートリアルがあれば、これらすべてを指摘できればよかったのにと思います。私が推測する別の本の飼料...

これにより、JPA は、参照されたオブジェクトをデータベースから実際にロードするようになります。

public List<Apple> getApples(Kid kid) throws KidNotFoundException 
{
    log.info("getApples (service) called"); 
    kid = get(kid);
    List<Apple> list = kid.getApples();
    list.size();
    return list;
}

私の場合、これが「java.sql.SQLException: フィールド 'xxxx' にデフォルト値がありません」というメッセージを生成する最初の問題でした。

2 つ目の問題は、2 つのテーブル間に不適切に構成された @ManyToMany 関係に関係していました。今日、私が以前に作成したプロトタイプから、多対多の関係であると思われるものをセットアップするのに約 5 分かかりました。よじれを解消するのに約6時間の髪の引っ張りが必要でした. いずれにせよ、これは私が自分の状況を解決するためにやったことです。

/**
 * "Buckets"
 * an Apple can be give to 0-to-n Kids ... 
 */

@ManyToMany(cascade=CascadeType.PERSIST)
@JoinTable(name="Buckets",
    joinColumns=@JoinColumn(name="Apple_id"),
    inverseJoinColumns=@JoinColumn(name="Kid_id"))
private List<Kid> kids;

public List<Kid> getKids() {
    return kids;
}

public void setKids(List<Kid> kids) {
    this.kids = kids;
}

. . .

/**
 * a Kid can have 0-n Apples
 */

@ManyToMany(mappedBy="kids", cascade=CascadeType.PERSIST)
private List<Apple> apples;

それと、私の元の @ManyToMany セットアップが間違ったテーブルを参照していたという事実が、私の場合、このエラーに貢献しました。しかし、LAZY LOAD の状況を簡単に修正するだけで、「java.sql.SQLException: フィールド 'xxxx' にデフォルト値がありません」という問題がすぐに解決されました。

ペリー

Ps。一日中、私は JPA のラフな外観の下に隠された巧妙なトリックをいくつか学びました (つまり、Web をサーフィンしたり、@ManyToMany 関係を効率的に使用する方法に関するドキュメントを読んだり)。上記の構成により、手動で作成したかのように見える 3 番目のデータベース テーブルが動的に作成されます。また、1 対 1 の関係に関する限り、Kids と Apple の間に独自の関係を強制します。データベースに 2 つの同一のテーブルを必要とする代わりに、データベースに追加のテーブルを 1 つだけ作成します。実際、私の場合、この @ManyToMany コンストラクトの前に 2 つのテーブルがありました。

キッズりんご

上記のようにリストされた @ManyTo@Many コンストラクトの結果として、3 つになりました。

キッズりんごバケツ

Buckets テーブル内には、Apple_id と Kid_id の 2 つのフィールドしかありません。重要なのは、両方にエントリを追加する場合です。

kids.add(apple);
apple.add(kids);

Buckets テーブルには 1 つのレコードしかなく、2 つではありません! Set<> (aka. unique ) の代わりに List<> を使用しようとしている場合、これは非常に重要です。

于 2015-01-09T21:20:59.807 に答える
0

同様に同じ列catVerb_idを使用する場合@JoinColumn

@JoinColumn(name="catVerb_id", nullable = true) 

に変更してみてください

@JoinColumn(name="catVerb_id", insertable = false, updatable = false) 

あなたの場合は主キーであるため、nullにすることはできません。

于 2013-06-07T01:29:05.090 に答える