我已经打了好几个小时了。我是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();
}
}
}
不幸的是我收到了以下异常,坦率地说我真的不知道为什么,父(testTeam
)的实例已经保存了,不是吗?
java.sql.SQLIntegrityConstraintViolationException:完整性约束违规:外键没有父级; FK_NMC24E737IXMNI0G869QRBOUI表:TEST_PLAYER
我在这里做错了什么?
这实际上很奇怪。如果我将@Id
类的TestPlayer
定义为long类型的字段,那么一切似乎都正常。
@Id
private long playerId;
之后更改了一个到多个注释
@OneToMany(mappedBy = "playerId")
这个星座不会产生任何异常。问题是,为什么我不能使用String
类型作为标识符???
答案 0 :(得分:2)
我没有在我面前有一个环境,但我认为问题在于您试图坚持testTeam
而没有先坚持testPlayer1
(或testPlayer2
)。在@OneToMany
注释中,您尚未指定cascade = {Cascade.PERSIST}
,这意味着这些播放器不会自动保存到testTeam
。