完整性约束违规
使用Play!框架,我有以下两种模式:完整性约束违规
@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, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?)]
任何人都可以帮助我erstand错误意味着什么,我做错了什么?
这里的问题是Site模型类和User模型类之间的映射。给出的错误是缺少一个外键。
如果您在用户类中注释掉网站列表,您的测试将通过。这样就缩小了问题范围。
更新:
问题是因为当你的网站对象被保存,这将节省的子对象第一(其中包括用户对象)。发生这种情况时,它尝试创建对Site对象的引用(由于mappedBy参数),但尚未保存(这将在保存User对象后完成)。
因此,另一种方法是根据您有权访问的值(例如siteId)进行映射,或者在保存后将用户添加到站点(因此已生成ID值)
我改变你的代码mappedBy="siteId"
和试运行的罚款。
对我来说很好! – 2010-12-12 10:44:37
我想你的建议,现在我得到这个错误: – 2010-12-12 14:19:17
09:17:54710 ERROR〜不成功:ALTER TABLE网站加入索引FK2753671A145791( 网站ID),加约束FK2753671A145791外键(网站ID)引用的用户(我 d) 09:17:54,710错误〜BLOB/TEXT列'siteId'在密钥规范中使用,没有 密钥长度为 – 2010-12-12 14:20:15
我通过使用甲骨文“初期递延DEFERRABLE”解决这样的问题,直到您提交整个事务这延迟的检查!
我不确定这是否是问题的原因,但Hibernate需要“所有持久化类必须具有默认构造函数”(更精确,无参数构造函数)。我没有看到它的网站和用户。 – Ralph 2010-12-12 09:37:29