@Entity
@Table(name="TEACHERS")
@SequenceGenerator(name="SEQ_TEACHERS",sequenceName="SEQ_TEACHERS")
public class Teacher {
private Long id;
private String code;
private String name;
private String type;
private List<Student> students;
@Id
@GeneratedValue(generator="SEQ_TEACHERS",strategy=GenerationType.SEQUENCE)
@Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name="CODE")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(name="NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="TYPE")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="TECH_ID",nullable=true,updatable=true)
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
@Entity
@Table(name="STUDENTS")
@SequenceGenerator(name="SEQ_STUDENTS",sequenceName="SEQ_STUDENTS")
public class Student {
private Long id;
private String code;
private String name;
// @Column(name="TECH_ID")
// private Long techId;
private Teacher teacher;
@Id
@GeneratedValue(generator="SEQ_STUDENTS",strategy=GenerationType.SEQUENCE)
@Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name="CODE")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Column(name="NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// public Long getTechId() {
// return techId;
// }
// public void setTechId(Long techId) {
// this.techId = techId;
// }
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="TECH_ID")
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
public class AssociationsTest {
/**
* @param args
*/
public static void main(String[] args) {
// SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction trans = session.beginTransaction();
Teacher t = new Teacher();
t.setCode("000001");
t.setName("xiaoxue");
t.setType("shuxue");
List<Student> list = new ArrayList<Student>();
Student s0 = new Student();
s0.setCode("000001");
s0.setName("xioali");
list.add(s0);
Student s1 = new Student();
s1.setCode("000002");
s1.setName("zhangsan");
list.add(s1);
t.setStudents(list);
session.save(t);
trans.commit();
}
}
执行到 session.save(t);时,报如下错误:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.myHibernate.test.AssociationsTest.main(AssociationsTest.java:39)
Caused by: java.sql.BatchUpdateException: ORA-01400: 无法将 NULL 插入 ("SYSTEM"."STUDENTS"."TECH_ID")
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:367)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:8739)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 8 more
7 个解决方案
#1
你设了级联,你在保存一这方,多的那方也会保存,
但是多的那方你要保证每个字段都有值,或可以为空,或者有默认值。
比如
a 表 e,f,d 三个字段,
b, 表有 x,y,e,e是引用a的e做外键,
你插人a时,
b,也会插,这是b表里只有e这个字段有值,x,y是空的,如果没有默认值,后值不允许为空,
这时 b表就会报错
但是多的那方你要保证每个字段都有值,或可以为空,或者有默认值。
比如
a 表 e,f,d 三个字段,
b, 表有 x,y,e,e是引用a的e做外键,
你插人a时,
b,也会插,这是b表里只有e这个字段有值,x,y是空的,如果没有默认值,后值不允许为空,
这时 b表就会报错
#2
刚没看你的代码,就说了堆废话,
映射这里有问题
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="TECH_ID",nullable=true,updatable=true)
这个注解,改为
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER ,mappedBy ="teacher")
映射这里有问题
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="TECH_ID",nullable=true,updatable=true)
这个注解,改为
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER ,mappedBy ="teacher")
#3
@JoinColumn(name="TECH_ID",nullable=true,updatable=true) ,不要
#4
先谢谢,热心的ZuxiangHuang,你的回复给我了点提示。后来经过多次测试,有了问题的解决方案。在注解上的写法上有问题:
Teacher类中的students属性的注解:@OneToMany(fetch=FetchType.EAGER,mappedBy="teacher",cascade=CascadeType.ALL),Student类中的teacher属性上的注解:@ManyToOne @JoinColumn(name="TECH_ID")
在单元测试代码中也有错误,两个student对象要设置teacher属性值,即:s0.setTeacher(t),s1.setTeacher(t),这样的话就可以解决问题了。
Teacher类中的students属性的注解:@OneToMany(fetch=FetchType.EAGER,mappedBy="teacher",cascade=CascadeType.ALL),Student类中的teacher属性上的注解:@ManyToOne @JoinColumn(name="TECH_ID")
在单元测试代码中也有错误,两个student对象要设置teacher属性值,即:s0.setTeacher(t),s1.setTeacher(t),这样的话就可以解决问题了。
#5
还可以看我的博客hibernate 一对多
#6
这是Goods表,商品表
这是一个实体的代码,接下来我在发一个实体的代码。
我想
我想在主键表中先插入数据,外键表后续插入,请问大家有没有什么好的解决方案.以下是我的测试单元,为何外键表插入不了数据。
package com.eifashion.brand.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import com.eifashion.portal.model.FuncClassify;
@Entity(name = "brand_goods")
public class Goods implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String name;
private Brand brand;
//商品品牌分类操作
private FuncClassify funClassify;
private List<BrandTagValue> tagValue;
private List<GoodsBarcode> barcodes;
public Goods(String id) {
super();
this.id = id;
}
public Goods(){}
public Goods(String id, String name, Brand brand, FuncClassify funcClassify) {
super();
this.id = id;
this.name = name;
this.brand = brand;
this.funClassify = funcClassify;
}
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinColumn(name = "fun_id")
public FuncClassify getFunClassify() {
return funClassify;
}
public void setFunClassify(FuncClassify funClassify) {
this.funClassify = funClassify;
}
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinTable(name = "brand_goods_tag", joinColumns = @JoinColumn(name = "goods_id"), inverseJoinColumns = @JoinColumn(name = "tag_id"))
public List<BrandTagValue> getTagValue() {
return tagValue;
}
public void setTagValue(List<BrandTagValue> tagValue) {
this.tagValue = tagValue;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy =
"good", targetEntity = GoodsBarcode.class)
public List<GoodsBarcode> getBarcodes() {
return barcodes;
}
public void setBarcodes(List<GoodsBarcode> barcodes) {
this.barcodes = barcodes;
}
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinColumn(name = "brand_id")
public Brand getBrand() {
return brand;
}
public void setBrand(Brand brand) {
this.brand = brand;
}
public void addBrandTag(BrandTagValue brandTag){
if(tagValue==null)
tagValue = new ArrayList<BrandTagValue>();
tagValue.add(brandTag);
}
public void addGoodsBar(GoodsBarcode goodsBarcode){
if(goodsBarcode == null)
barcodes = new ArrayList<GoodsBarcode>();
barcodes.add(goodsBarcode);
}
}
这是一个实体的代码,接下来我在发一个实体的代码。
我想
package com.eifashion.portal.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import com.eifashion.brand.model.BrandFuncClassify;
import com.eifashion.brand.model.Goods;
import com.eifashion.common.util.PinYinUtils;
/**
* 商品功能分类
*
* @author tommyzhao
*
*/
@Entity(name = "portal_func_class")
public class FuncClassify implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public final static String DEFAULT_FUNC = "nanzhuang";
private String id;
private FuncClassify parent;
private String name;
private long sort;
private List<FuncClassify> children;
private Date createTime;
private String description;
private List<Goods> goods;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy =
"funClassify", targetEntity = Goods.class)
public List<Goods> getGoods() {
return goods;
}
public void addGoods(Goods goods)
{
if(this.goods == null)
{
this.goods = new ArrayList<Goods>();
}
this.goods.add(goods);
}
public void setGoods(List<Goods> goods) {
this.goods = goods;
}
public FuncClassify() {
}
public FuncClassify(String name) {
super();
this.name = name;
this.id = PinYinUtils.toHanyuPinyinString(name);
}
public FuncClassify(String name, String description, FuncClassify parent) {
super();
this.parent = parent;
this.name = name;
this.id = PinYinUtils.toHanyuPinyinString(name);
this.description = description;
this.createTime = new Date();
}
public FuncClassify(String name, String description) {
super();
this.name = name;
this.id = PinYinUtils.toHanyuPinyinString(name);
this.description = description;
this.createTime = new Date();
}
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
public FuncClassify getParent() {
return parent;
}
public void setParent(FuncClassify parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getSort() {
return sort;
}
public void setSort(long sort) {
this.sort = sort;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent", targetEntity = FuncClassify.class)
public List<FuncClassify> getChildren() {
return children;
}
public void setChildren(List<FuncClassify> children) {
this.children = children;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void addChild(FuncClassify child) {
if (children == null) {
children = new ArrayList<FuncClassify>();
}
children.add(child);
}
}
我想在主键表中先插入数据,外键表后续插入,请问大家有没有什么好的解决方案.以下是我的测试单元,为何外键表插入不了数据。
@Test
public void addGoods()
{
Brand brand = new Brand();
FuncClassify funcclass = new FuncClassify();
Goods goods = new Goods();
goods.setId("aaarr");
goods.setName("bbbb");
brand.addGoods(goods);
funcclass.addGoods(goods);
goodsDAO.addGoods(goods);
}
#7
在goodsDAO.addGoods这段代码前加goods.setFunClassify(FuncClassify funClassify),试试看。
#1
你设了级联,你在保存一这方,多的那方也会保存,
但是多的那方你要保证每个字段都有值,或可以为空,或者有默认值。
比如
a 表 e,f,d 三个字段,
b, 表有 x,y,e,e是引用a的e做外键,
你插人a时,
b,也会插,这是b表里只有e这个字段有值,x,y是空的,如果没有默认值,后值不允许为空,
这时 b表就会报错
但是多的那方你要保证每个字段都有值,或可以为空,或者有默认值。
比如
a 表 e,f,d 三个字段,
b, 表有 x,y,e,e是引用a的e做外键,
你插人a时,
b,也会插,这是b表里只有e这个字段有值,x,y是空的,如果没有默认值,后值不允许为空,
这时 b表就会报错
#2
刚没看你的代码,就说了堆废话,
映射这里有问题
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="TECH_ID",nullable=true,updatable=true)
这个注解,改为
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER ,mappedBy ="teacher")
映射这里有问题
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="TECH_ID",nullable=true,updatable=true)
这个注解,改为
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER ,mappedBy ="teacher")
#3
@JoinColumn(name="TECH_ID",nullable=true,updatable=true) ,不要
#4
先谢谢,热心的ZuxiangHuang,你的回复给我了点提示。后来经过多次测试,有了问题的解决方案。在注解上的写法上有问题:
Teacher类中的students属性的注解:@OneToMany(fetch=FetchType.EAGER,mappedBy="teacher",cascade=CascadeType.ALL),Student类中的teacher属性上的注解:@ManyToOne @JoinColumn(name="TECH_ID")
在单元测试代码中也有错误,两个student对象要设置teacher属性值,即:s0.setTeacher(t),s1.setTeacher(t),这样的话就可以解决问题了。
Teacher类中的students属性的注解:@OneToMany(fetch=FetchType.EAGER,mappedBy="teacher",cascade=CascadeType.ALL),Student类中的teacher属性上的注解:@ManyToOne @JoinColumn(name="TECH_ID")
在单元测试代码中也有错误,两个student对象要设置teacher属性值,即:s0.setTeacher(t),s1.setTeacher(t),这样的话就可以解决问题了。
#5
还可以看我的博客hibernate 一对多
#6
这是Goods表,商品表
这是一个实体的代码,接下来我在发一个实体的代码。
我想
我想在主键表中先插入数据,外键表后续插入,请问大家有没有什么好的解决方案.以下是我的测试单元,为何外键表插入不了数据。
package com.eifashion.brand.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import com.eifashion.portal.model.FuncClassify;
@Entity(name = "brand_goods")
public class Goods implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String name;
private Brand brand;
//商品品牌分类操作
private FuncClassify funClassify;
private List<BrandTagValue> tagValue;
private List<GoodsBarcode> barcodes;
public Goods(String id) {
super();
this.id = id;
}
public Goods(){}
public Goods(String id, String name, Brand brand, FuncClassify funcClassify) {
super();
this.id = id;
this.name = name;
this.brand = brand;
this.funClassify = funcClassify;
}
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinColumn(name = "fun_id")
public FuncClassify getFunClassify() {
return funClassify;
}
public void setFunClassify(FuncClassify funClassify) {
this.funClassify = funClassify;
}
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinTable(name = "brand_goods_tag", joinColumns = @JoinColumn(name = "goods_id"), inverseJoinColumns = @JoinColumn(name = "tag_id"))
public List<BrandTagValue> getTagValue() {
return tagValue;
}
public void setTagValue(List<BrandTagValue> tagValue) {
this.tagValue = tagValue;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy =
"good", targetEntity = GoodsBarcode.class)
public List<GoodsBarcode> getBarcodes() {
return barcodes;
}
public void setBarcodes(List<GoodsBarcode> barcodes) {
this.barcodes = barcodes;
}
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinColumn(name = "brand_id")
public Brand getBrand() {
return brand;
}
public void setBrand(Brand brand) {
this.brand = brand;
}
public void addBrandTag(BrandTagValue brandTag){
if(tagValue==null)
tagValue = new ArrayList<BrandTagValue>();
tagValue.add(brandTag);
}
public void addGoodsBar(GoodsBarcode goodsBarcode){
if(goodsBarcode == null)
barcodes = new ArrayList<GoodsBarcode>();
barcodes.add(goodsBarcode);
}
}
这是一个实体的代码,接下来我在发一个实体的代码。
我想
package com.eifashion.portal.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import com.eifashion.brand.model.BrandFuncClassify;
import com.eifashion.brand.model.Goods;
import com.eifashion.common.util.PinYinUtils;
/**
* 商品功能分类
*
* @author tommyzhao
*
*/
@Entity(name = "portal_func_class")
public class FuncClassify implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public final static String DEFAULT_FUNC = "nanzhuang";
private String id;
private FuncClassify parent;
private String name;
private long sort;
private List<FuncClassify> children;
private Date createTime;
private String description;
private List<Goods> goods;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy =
"funClassify", targetEntity = Goods.class)
public List<Goods> getGoods() {
return goods;
}
public void addGoods(Goods goods)
{
if(this.goods == null)
{
this.goods = new ArrayList<Goods>();
}
this.goods.add(goods);
}
public void setGoods(List<Goods> goods) {
this.goods = goods;
}
public FuncClassify() {
}
public FuncClassify(String name) {
super();
this.name = name;
this.id = PinYinUtils.toHanyuPinyinString(name);
}
public FuncClassify(String name, String description, FuncClassify parent) {
super();
this.parent = parent;
this.name = name;
this.id = PinYinUtils.toHanyuPinyinString(name);
this.description = description;
this.createTime = new Date();
}
public FuncClassify(String name, String description) {
super();
this.name = name;
this.id = PinYinUtils.toHanyuPinyinString(name);
this.description = description;
this.createTime = new Date();
}
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH }, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
public FuncClassify getParent() {
return parent;
}
public void setParent(FuncClassify parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getSort() {
return sort;
}
public void setSort(long sort) {
this.sort = sort;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent", targetEntity = FuncClassify.class)
public List<FuncClassify> getChildren() {
return children;
}
public void setChildren(List<FuncClassify> children) {
this.children = children;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void addChild(FuncClassify child) {
if (children == null) {
children = new ArrayList<FuncClassify>();
}
children.add(child);
}
}
我想在主键表中先插入数据,外键表后续插入,请问大家有没有什么好的解决方案.以下是我的测试单元,为何外键表插入不了数据。
@Test
public void addGoods()
{
Brand brand = new Brand();
FuncClassify funcclass = new FuncClassify();
Goods goods = new Goods();
goods.setId("aaarr");
goods.setName("bbbb");
brand.addGoods(goods);
funcclass.addGoods(goods);
goodsDAO.addGoods(goods);
}
#7
在goodsDAO.addGoods这段代码前加goods.setFunClassify(FuncClassify funClassify),试试看。