[英]Simple scenario ends with “integrity constraint violation”
我已经为此战斗了好几个小时。 我是Hibernate的新手,我想使用Hibernate 4和HSQLDB(版本2.3.2)进行一些基本映射。
这是我的代码:
package utils;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "TEST_TEAM")
public final class TestTeam {
@Id
@Column(name = "NAME")
private String name;
@OneToMany(mappedBy = "name", fetch = FetchType.EAGER)
private List<TestPlayer> test1List;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<TestPlayer> getTest1List() {
return test1List;
}
public void setTest1List(List<TestPlayer> test1List) {
this.test1List = test1List;
}
public TestTeam() {
}
public TestTeam(final String name, final List<TestPlayer> test1List) {
this.name = name;
this.test1List = new ArrayList<>(test1List);
}
}
package utils;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name = "TEST_PLAYER")
public class TestPlayer {
@Id
@Column(name = "NAME")
private String name;
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "TEST_NAME", nullable = false)
private TestTeam test;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "PREVIOUS_TEST_TEAM")
private Map<Integer, TestTeam> previousTests;
public TestPlayer() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TestTeam getTest() {
return test;
}
public void setTestTeam(TestTeam test) {
this.test = test;
}
public Map<Integer, TestTeam> getPreviousTests() {
return previousTests;
}
public void setPreviousTests(Map<Integer, TestTeam> previousTests) {
this.previousTests = previousTests;
}
public TestPlayer(final String name, final TestTeam test,
final Map<Integer, TestTeam> previousTests) {
this.name = name;
this.test = test;
this.previousTests = new HashMap<>(previousTests);
}
}
而应该运行所有代码并很好地持久保存实例的代码。
package utils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class TestHibernate {
private static final SessionFactory SESSION_FACTORY;
static {
final Properties properties = new Properties();
properties.setProperty("hibernate.connection.driver_class",
"org.hsqldb.jdbcDriver");
properties.setProperty("hibernate.connection.url",
"jdbc:hsqldb:hsql://localhost/xdb");
properties.setProperty("hibernate.connection.username", "SA");
properties.setProperty("hibernate.connection.password", "");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.format_sql", "true");
properties.setProperty("hibernate.hbm2ddl.auto", "create");
properties.setProperty("hibernate.dialect",
"org.hibernate.dialect.HSQLDialect");
final Configuration configuration = new Configuration();
configuration.setProperties(properties).addPackage("utils")
.addAnnotatedClass(TestTeam.class)
.addAnnotatedClass(TestPlayer.class);
final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
SESSION_FACTORY = configuration.buildSessionFactory(serviceRegistry);
final SchemaExport schemaExport = new SchemaExport(configuration);
schemaExport.setOutputFile("schema.sql");
schemaExport.create(true, false);
}
public static void main(String[] args) {
try {
final TestTeam previousTestTeam = new TestTeam();
previousTestTeam.setName("previousTest");
final TestTeam testTeam = new TestTeam();
testTeam.setName("Test");
final TestPlayer testPlayer1 = new TestPlayer();
testPlayer1.setName("Test1");
testPlayer1.setTestTeam(testTeam);
final Map<Integer, TestTeam> previousTestMap = new HashMap<>();
previousTestMap.put(1, previousTestTeam);
testPlayer1.setPreviousTests(previousTestMap);
final TestPlayer testPlayer2 = new TestPlayer();
testPlayer2.setName("Test2");
testPlayer2.setTestTeam(testTeam);
List<TestPlayer> test1List = Arrays
.asList(testPlayer1, testPlayer2);
testTeam.setTest1List(test1List);
final Session session = SESSION_FACTORY.openSession();
session.beginTransaction();
session.saveOrUpdate(previousTestTeam);
session.saveOrUpdate(testTeam);
session.saveOrUpdate(testPlayer1);
session.getTransaction().commit();
session.close();
} finally {
SESSION_FACTORY.close();
}
}
}
不幸的是,我遇到了以下异常,并且坦率地说,我真的不知道为什么,parent( testTeam
)的实例已经保存了,不是吗?
java.sql.SQLIntegrityConstraintViolationException:违反完整性约束:外键没有父级; FK_NMC24E737IXMNI0G869QRBOUI表:TEST_PLAYER
我在这里做错了什么?
这实际上很奇怪。 如果我将TestPlayer
类的@Id
定义为TestPlayer
类型的字段,那么一切似乎都正常。
@Id
private long playerId;
之后更改为一对多注释
@OneToMany(mappedBy = "playerId")
这个星座不会产生任何异常。 问题是,为什么我不能使用String
类型作为标识符???
我前面没有环境,但是我认为问题是您在不首先testPlayer1
(或testPlayer2
)的情况下尝试保留testTeam
。 在@OneToMany
批注上,您未指定cascade = {Cascade.PERSIST}
,这意味着保存到testTeam
不会自动保留这些播放testTeam
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.