gpt4 book ai didi

mysql - JPA 在同一事务中插入父实体和子实体

转载 作者:行者123 更新时间:2023-11-29 08:29:05 28 4
gpt4 key购买 nike

我完全陷入了这件事,也许有人可以帮忙。

我有两个实体,父实体和子实体。 Test1Entity 是父级,Test1ChildEntity 是子级。当然,很好的命名。数据库是Mysql,JPA提供者是Hibernate。以下是这两个实体的定义:

@Table(name = "Test1", schema = "", catalog = "")
@Entity
public class Test1Entity {
private int id;

@Column(name = "id")
@Id
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

private String name;

@Column(name = "name")
@Basic
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Test1Entity that = (Test1Entity) o;

if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;

return true;
}

@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}

private Collection<Test1ChildEntity> test1ChildrenById;

@OneToMany(mappedBy = "test1ByParentId")
public Collection<Test1ChildEntity> getTest1ChildrenById() {
return test1ChildrenById;
}

public void setTest1ChildrenById(Collection<Test1ChildEntity> test1ChildrenById) {
this.test1ChildrenById = test1ChildrenById;
}

}


@Table(name = "Test1_Child", schema = "", catalog = "")
@Entity
public class Test1ChildEntity {
private int id;

@Column(name = "id")
@Id
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

private String name;

@Column(name = "name")
@Basic
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Test1ChildEntity that = (Test1ChildEntity) o;

if (id != that.id) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;

return true;
}

@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}

private Test1Entity test1ByParentId;

@ManyToOne
@JoinColumn(name = "parent_id")
public Test1Entity getTest1ByParentId() {
return test1ByParentId;
}

public void setTest1ByParentId(Test1Entity test1ByParentId) {
this.test1ByParentId = test1ByParentId;
}
}

尝试在同一事务中插入一个父级和一个子级的代码如下:

@Transactional
public void createItWell(String parentName, String childName) {

Test1Entity parent = new Test1Entity();

parent.setName(parentName);

Test1ChildEntity child = new Test1ChildEntity();

child.setName(childName);
child.setTest1ByParentId(parent);

Set<Test1ChildEntity> mySet = new HashSet<>();

mySet.add(child);
parent.setTest1ChildrenById(mySet);

this.entityManager.persist(parent);
this.entityManager.persist(child);

}

尝试执行此代码时出现以下异常:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`comwork`.`test1_child`, CONSTRAINT `test1_child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `Test1` (`id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)

插入其他实体,独立(不涉及关系)工作得很好。

两个表定义是:

CREATE TABLE `Test1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

LOCK TABLES `Test1` WRITE;
/*!40000 ALTER TABLE `Test1` DISABLE KEYS */;

INSERT INTO `Test1` (`id`, `name`)
VALUES
(6,'Parent');

/*!40000 ALTER TABLE `Test1` ENABLE KEYS */;
UNLOCK TABLES;


# Dump of table Test1_Child
# ------------------------------------------------------------

CREATE TABLE `Test1_Child` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) unsigned NOT NULL,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `test1_child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `Test1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我是 JPA 新手,很抱歉这可能是一个微不足道的问题。

谢谢。

最佳答案

尝试在 OneToMany 关系上设置 Cascade 属性:

@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
private Collection<Test1ChildEntity> test1ChildrenById;

关于mysql - JPA 在同一事务中插入父实体和子实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17150728/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com