[英](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
);
任何幫助將不勝感激,謝謝。
更新 - 解決問題
嗯,我期待一個勝利的配樂,但沒關系......
我只是按照這個鏈接說的:
我讀到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.