简单的场景以"完整性约束违规结束"

时间:2014-09-01 16:50:13

标签: java hibernate hsqldb

我已经打了好几个小时了。我是Hibernate的新手,我想使用Hibernate 4和HSQLDB(版本2.3.2)进行一些基本的映射。

这是我的代码:

TestTeam.java

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);
    }
}

TestPlayer.java

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);
    }
}

应该运行它的代码并很好地保留实例。

TestHibernate.java

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类型作为标识符???

1 个答案:

答案 0 :(得分:2)

我没有在我面前有一个环境,但我认为问题在于您试图坚持testTeam而没有先坚持testPlayer1 (或testPlayer2)。在@OneToMany注释中,您尚未指定cascade = {Cascade.PERSIST},这意味着这些播放器不会自动保存到testTeam