簡體   English   中英

(Hibernate)java.sql.SQLException:字段'xxxx'沒有默認值

[英](Hibernate) java.sql.SQLException: Field 'xxxx' doesn't have a default value

Hibernate拋出以下異常:

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

人們說問題在於我的PK沒有AUTO_INCREMENT語句,但你可以看到我在我的數據庫中完成了這個並且問題仍在繼續。 所以,我帶來了我的類和我的數據庫實現。

我認為我的問題出在測試課上......有人可以告訴我如何測試這個?

(是的,有些單詞是葡萄牙語,但你可以理解)。

CategoriaVerbete

@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;
    }

}

Verbete

@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;
    }

    ...
}

SignificadosVerbete

@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文檔不推薦該鏈接中的內容,但我嘗試遵循recomendations並通過一周處理錯誤。 所以,我希望這有助於其他人。

並感謝所有的答案。

我相信這是一個導致cannot be null問題的SignificadosVerbete插件(我強烈建議您打開sql跟蹤以查看哪個查詢導致問題)。

這是雙向一對多關系的常見問題。 你有什么是這樣的:

class Foo {
    @Id
    @Column("foo_id")
    Long id;

    @OneToMany(cascade=ALL)
    @JoinColumn("foo_id")
    Set<Bar> bars;
}

class Bar {
    @Id
    @Column("bar_id")
    Long id;

    @ManyToOne
    @JoinColumn("foo_id", insertable=false, updatable=false)
    Foo foo;
}

這種映射將導致關系由Foo擁有,這將創建多個insert+update語句:當您插入Foo ,使用2個Bar ,將會發生的事情是它將首先插入Foo ,以及2 沒有 FK foo_id酒吧。 然后將為每個Bar發出兩個更新,以更新Bar表中的正確foo_id

通常我們不會以這種方式映射雙向OneToMany映射,我們這樣做:

class Foo {
    @Id
    @Column("foo_id")
    Long id;

    @OneToMany(mappedBy="foo", cascade=ALL)
    Set<Bar> bars;
}

class Bar {
    @Id
    @Column("bar_id")
    Long id;

    @ManyToOne
    @JoinColumn("foo_id")
    Foo foo;
}

通過這樣做,關系由Bar擁有,當你按照我的描述插入時,你將插入1個Foo和2個已經將foo_id作為插入的一部分的Bar

這就是我們通常在Hibernate中進行雙向關系的方式。

我同意提供的鏈接。 它遵循鏈接。 據我所知,刪除下面的部分確實對我有用。

之前:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="catVerb_id", insertable = false, updatable = false)

后:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="catVerb_id")

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;
}

你必須添加一個看起來微不足道的步驟。 要觸發JPA的Lazy Load機制,您需要在引用的對象本身上調用一個方法(它只能在JPA事務內部工作,無論是直接還是隱含的@Stateless標記)。 直到你這樣做,JPA最好不要將不必要的對象加載到內存中(也就是Fetch.LAZY背后的整個想法 )。

所以在這種情況下,我在檢索到的(Fetch.LAZY指定)對象'列表'上調用一個方法:

 list.size();

可以調用對象上的任何方法來觸發JPA來加載對象(或對象),在這種情況下我只是調用了list.size()方法就這么方便了,它看起來並不像以前那么多叫一個看似不必要的孩子.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'在我的情況下沒有默認值'消息。

第二個問題與兩個表之間未正確配置的@ManyToMany關系有關。 今天,我花了大約五分鍾來設置我之前創建的原型的多對多關系。 需要大約六個小時的時間才能解決問題。 無論如何,這就是我最終要解決的問題。

/**
 * "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:Field'xxxx'沒有立即的默認值'問題。

佩里

PS。 一整天之后,我確實學到了隱藏在JPA粗糙外表下的一些巧妙的技巧(也就是說,瀏覽網頁和閱讀有關如何有效使用@ManyToMany關系的文檔)。 這樣,上面的配置將動態創建第三個數據庫表,看起來就像手動創建它一樣好。 就一對一的關系而言,它還強制了孩子和蘋果之間的獨特關系。 除了在數據庫中只創建一個額外的表,而不是在數據庫中需要兩個相同的表。 實際上,在我的情況下,我在這個@ManyToMany構造之前有2個表:

兒童蘋果

由於上面列出的@ ManyTo @ Many結構,我現在有3個:

兒童蘋果桶

在Buckets表中只有兩個字段,Apple_id和Kid_id,重要的是當我向兩個字段添加一個條目時:

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

Buckets表中只有一條記錄,而不是兩條記錄! 如果您嘗試使用List <>代替Set <>(也稱為unique),這一點非常重要。

如果對@JoinColumn使用相同的列catVerb_id

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

嘗試將其更改為

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

並且它不能為null,因為它是您案例中的主鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM