休眠中的一对多映射 ConstraintViolationException
One to many mapping ConstraintViolationException in hibernate
我有两个 tables,Theater 和 Shows,它们由一对多 mapping.I m 连接起来,试图按如下方式执行集合持久化。
public class Theater
{
private int theaterId;
private String theaterName;
private List<Shows> shows;
//getters and setters
}
public class Shows{
private int showId;
private String showType;
private int theaterId;
//getters and setters
}
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
Transaction t = s.beginTransaction();
Theater th = new Theater("iNox");
th.setTheaterId(4);
List<Shows> shs = new ArrayList<Shows>();
shs.add(new Shows("noon"));
shs.add(new Shows("Drama"));
th.setShows(shs);
s.save(th);
t.commit();
s.close();
xml映射
<class name="hibernate.Theater"
table="theater">
<id name="theaterId"
column ="theater_id">
<generator class="increment"></generator>
</id>
<list name="shows" table = "shows" cascade = "all" inverse = "false">
<key column="theater_id" />
<index column="show_id"/>
<one-to-many class = "hibernate.Shows"/>
</list>
<property name = "theaterName" column = "theater_name" />
</class>
<class name="hibernate.Shows"
table="shows">
<id name="showId"
column ="show_id">
<generator class="increment"></generator>
</id>
<property name = "showType" column = "show_type"/>
<property name = "theaterId" column = "theater_id"/>
</class>
在此处添加相关日志
12:19:43,435 DEBUG EntityPrinter:114 - Listing entities:
12:19:43,435 DEBUG EntityPrinter:121 - hibernate.Shows{showId=4, showType=Drama, theaterId=0}
12:19:43,435 DEBUG EntityPrinter:121 - hibernate.Theater{theaterName=iNox, theaterId=4, shows=[hibernate.Shows#3, hibernate.Shows#4]}
12:19:43,435 DEBUG EntityPrinter:121 - hibernate.Shows{showId=3, showType=noon, theaterId=0}
12:19:43,442 DEBUG SQL:109 - insert into sakila.theater (theater_name, theater_id) values (?, ?)
Hibernate: insert into sakila.theater (theater_name, theater_id) values (?, ?)
12:19:43,445 TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [iNox]
12:19:43,445 TRACE BasicBinder:81 - binding parameter [2] as [INTEGER] - [4]
12:19:43,446 DEBUG SQL:109 - insert into sakila.shows (show_type, theater_id, show_id) values (?, ?, ?)
Hibernate: insert into sakila.shows (show_type, theater_id, show_id) values (?, ?, ?)
12:19:43,447 TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [noon]
12:19:43,447 TRACE BasicBinder:81 - binding parameter [2] as [INTEGER] - [0]
12:19:43,447 TRACE BasicBinder:81 - binding parameter [3] as [INTEGER] - [3]
12:19:43,448 DEBUG SqlExceptionHelper:139 - could not execute statement [n/a]
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
根据日志,我猜 theaterID(从剧院 table 引用的外键)由自动 increment.But 正确生成(theaterID = 4),同时添加相应的节目,theaterID 用作0. 谁能指出这个问题的根本原因?
在 Shows Pojo 中,您将 threaterId 定义为 int,但它应该是 Threater pojo 的对象。
在 hibernate 中,如果你想使用 O2m 关系,你必须在 pojo 中定义相同的关系。
因此,为此您必须修改 Shows pojo as
public class Shows{
private int showId;
private String showType;
@OneToMany
@JoinColumn(name="theaterId")
private Threater theater;
//getters and setters
}
对我有用。请尝试
看起来我正在尝试双向关联,但忘记了在演出 class.Also 中包含剧院的多对一映射,正如 The N 所建议的,
需要用剧院参考替换剧院 ID。
添加了以下映射
<many-to-one
name="theater"
cascade="all"
column = "theater_id"
class="hibernate.Theater"/>
还发现 th.setTheaterId(4);
应该删除,因为 theaterId 是自动生成的。
我有两个 tables,Theater 和 Shows,它们由一对多 mapping.I m 连接起来,试图按如下方式执行集合持久化。
public class Theater
{
private int theaterId;
private String theaterName;
private List<Shows> shows;
//getters and setters
}
public class Shows{
private int showId;
private String showType;
private int theaterId;
//getters and setters
}
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
Transaction t = s.beginTransaction();
Theater th = new Theater("iNox");
th.setTheaterId(4);
List<Shows> shs = new ArrayList<Shows>();
shs.add(new Shows("noon"));
shs.add(new Shows("Drama"));
th.setShows(shs);
s.save(th);
t.commit();
s.close();
xml映射
<class name="hibernate.Theater"
table="theater">
<id name="theaterId"
column ="theater_id">
<generator class="increment"></generator>
</id>
<list name="shows" table = "shows" cascade = "all" inverse = "false">
<key column="theater_id" />
<index column="show_id"/>
<one-to-many class = "hibernate.Shows"/>
</list>
<property name = "theaterName" column = "theater_name" />
</class>
<class name="hibernate.Shows"
table="shows">
<id name="showId"
column ="show_id">
<generator class="increment"></generator>
</id>
<property name = "showType" column = "show_type"/>
<property name = "theaterId" column = "theater_id"/>
</class>
在此处添加相关日志
12:19:43,435 DEBUG EntityPrinter:114 - Listing entities:
12:19:43,435 DEBUG EntityPrinter:121 - hibernate.Shows{showId=4, showType=Drama, theaterId=0}
12:19:43,435 DEBUG EntityPrinter:121 - hibernate.Theater{theaterName=iNox, theaterId=4, shows=[hibernate.Shows#3, hibernate.Shows#4]}
12:19:43,435 DEBUG EntityPrinter:121 - hibernate.Shows{showId=3, showType=noon, theaterId=0}
12:19:43,442 DEBUG SQL:109 - insert into sakila.theater (theater_name, theater_id) values (?, ?)
Hibernate: insert into sakila.theater (theater_name, theater_id) values (?, ?)
12:19:43,445 TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [iNox]
12:19:43,445 TRACE BasicBinder:81 - binding parameter [2] as [INTEGER] - [4]
12:19:43,446 DEBUG SQL:109 - insert into sakila.shows (show_type, theater_id, show_id) values (?, ?, ?)
Hibernate: insert into sakila.shows (show_type, theater_id, show_id) values (?, ?, ?)
12:19:43,447 TRACE BasicBinder:81 - binding parameter [1] as [VARCHAR] - [noon]
12:19:43,447 TRACE BasicBinder:81 - binding parameter [2] as [INTEGER] - [0]
12:19:43,447 TRACE BasicBinder:81 - binding parameter [3] as [INTEGER] - [3]
12:19:43,448 DEBUG SqlExceptionHelper:139 - could not execute statement [n/a]
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
根据日志,我猜 theaterID(从剧院 table 引用的外键)由自动 increment.But 正确生成(theaterID = 4),同时添加相应的节目,theaterID 用作0. 谁能指出这个问题的根本原因?
在 Shows Pojo 中,您将 threaterId 定义为 int,但它应该是 Threater pojo 的对象。
在 hibernate 中,如果你想使用 O2m 关系,你必须在 pojo 中定义相同的关系。
因此,为此您必须修改 Shows pojo as
public class Shows{
private int showId;
private String showType;
@OneToMany
@JoinColumn(name="theaterId")
private Threater theater;
//getters and setters
}
对我有用。请尝试
看起来我正在尝试双向关联,但忘记了在演出 class.Also 中包含剧院的多对一映射,正如 The N 所建议的, 需要用剧院参考替换剧院 ID。
添加了以下映射
<many-to-one
name="theater"
cascade="all"
column = "theater_id"
class="hibernate.Theater"/>
还发现 th.setTheaterId(4);
应该删除,因为 theaterId 是自动生成的。