4

使用游戏!框架,我有以下两个模型:

@Entity
public class User extends Model {
    public String firstName;
    public String lastName;
    public String email;
    public String password;
    public boolean isAdmin;

    @OneToMany(mappedBy="id", cascade=CascadeType.ALL)
    public List<Site> sites;

    public User(String firstName, String lastName, String email, String password) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
    }

    public static User connect(String email, String password) {
        return User.find("byEmailAndPassword",email,Crypto.passwordHash(password)).first();
    }

    public static User findUser(String email) {
        return User.find("byEmail",email).first();
    }

    public static User createUser(String firstName, String lastName, String email, String password, boolean isAdmin) {
        String pw = Crypto.passwordHash(password);

        User u = new User(firstName, lastName, email, pw);
        u.isAdmin = isAdmin;
        u.save();
        return u;
    }
}

@Entity
public class Site extends Model {

    public UUID siteId;

    public String alias;
    public String protocol;
    public String host;
    public String username;
    public String password;
    public int port;
    public String rootPath;

    @Lob
    public String description;

    @ManyToOne
    public User user;

    public Site(User user, String alias, String protocol, String host, String username, String password) {
        this.user = user;
        this.alias = alias;
        this.protocol = protocol;
        this.host = host;
        this.username = username;
        this.password = password;
        this.port = 21;
        this.siteId = UUID.randomUUID();

    }
}

当我尝试运行以下测试时:

public class BasicTest extends UnitTest {

    @Before
    public void setup() {
        Fixtures.deleteAll();
    }

    @Test
    public void createAndRetrieveUser() {
        new User("Jason","Miesionczek","something","something").save();
        User jason = User.find("byEmail", "something").first();

        assertNotNull(jason);
        assertEquals("Jason", jason.firstName);
    }

    @Test
    public void userSite() {
        new User("Jason","Miesionczek","something","something").save();
        User jason = User.find("byEmail", "something").first();

        new Site(jason, "InterEditor","ftp","something","something","something").save();

        List<Site> sites = Site.find("byUser", jason).fetch();

        assertEquals(1, sites.size());

        Site site1 = sites.get(0);
        assertNotNull(site1);
        assertEquals("InterEditor", site1.alias);
        assertNotNull(site1.siteId);
    }



}

我得到这个错误:

A javax.persistence.PersistenceException has been caught, org.hibernate.exception.ConstraintViolationException: could not insert: [models.Site]
In /test/BasicTest.java, line 27 :
new Site(jason, "InterEditor","ftp","something","something","something").save();

日志输出:

00:06:26,184 WARN  ~ SQL Error: -177, SQLState: 23000
00:06:26,184 ERROR ~ Integrity constraint violation - no parent FK2753674FD92E0A
 table: USER in statement [insert into Site (id, alias, description, host, passw
ord, port, protocol, rootPath, siteId, user_id, username) values (null, ?, ?, ?,
 ?, ?, ?, ?, ?, ?, ?)]

谁能帮我理解错误的含义以及我做错了什么?

4

2 回答 2

6

您的问题是 Site 模型类和 User 模型类之间的映射。给出的错误是缺少外键。

如果您在 User 类中注释掉 Site 列表,您的测试将通过。这样就缩小了问题的范围。

更新:

问题是因为当您的 Site 对象被保存时,它会首先保存子对象(其中包括 User 对象)。发生这种情况时,它会尝试创建对 Site 对象的引用(由于 mappedBy 参数),但尚未保存(这将在保存 User 对象后完成)。

因此,另一种方法是按您有权访问的值(例如 siteId)进行映射,或者在保存用户后将用户添加到站点(因此生成了 ID 值。

我将您的代码更改为mappedBy="siteId"并且测试运行良好。

于 2010-12-12T10:14:07.950 回答
2

我通过在 Oracle 中使用“INITIALLY DEFERRED DEFERRABLE”解决了这样的问题,这会延迟检查,直到您提交整个事务!

于 2013-01-06T07:24:58.777 回答