我是 Hibernate+Derby 的新手...我在整个 google 中都看到了这个问题,但还没有找到合适的解决方案。
以下代码适用于 mysql,但当我在 derby 上尝试此代码时,出现异常:
(每个标签有两组文件,反之亦然 - manytomany)
标签.java
@Entity
@Table(name="TAGS")
public class Tags implements Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public long getId()
{
return id;
}
@ManyToMany(targetEntity=Files.class
)
@ForeignKey(name="USER_TAGS_FILES",inverseName="USER_FILES_TAGS")
@JoinTable(name="USERTAGS_FILES",
joinColumns=@JoinColumn(name="TAGS_ID"),
inverseJoinColumns=@JoinColumn(name="FILES_ID"))
public Set<data.Files> getUserFiles()
{
return userFiles;
}
@ManyToMany(mappedBy="autoTags",
targetEntity=data.Files.class)
public Set<data.Files> getAutoFiles()
{
return autoFiles;
}
文件.java
@Entity
@Table(name="FILES")
public class Files implements Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public long getId()
{
return id;
}
@ManyToMany(mappedBy="userFiles",
targetEntity=data.Tags.class)
public Set getUserTags()
{
return userTags;
}
@ManyToMany(targetEntity=Tags.class
)
@ForeignKey(name="AUTO_FILES_TAGS",inverseName="AUTO_TAGS_FILES")
@JoinTable(name="AUTOTAGS_FILES",
joinColumns=@JoinColumn(name="FILES_ID"),
inverseJoinColumns=@JoinColumn(name="TAGS_ID"))
public Set getAutoTags()
{
return autoTags;
}
我向数据库添加了一些数据,但是在运行 Derby 时出现了这些异常(不使用 mysql)
异常(exception)情况
SEVERE: DELETE on table 'FILES' caused a violation of foreign key constraint 'USER_FILES_TAGS' for key (3). The statement has been rolled back.
Jun 10, 2010 9:49:52 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete: [data.Files#3]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2712)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2895)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:97)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:613)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)
at $Proxy13.flush(Unknown Source)
at data.HibernateORM.removeFile(HibernateORM.java:285)
at data.DataImp.removeFile(DataImp.java:195)
at booting.DemoBootForTestUntilTestClassesExist.main(DemoBootForTestUntilTestClassesExist.java:62)
我以前从未使用过 Derby ,所以也许我缺少一些重要的东西
1)我做错了什么?
2) 当我在两个类之间有 2 个多对多关系时,有什么方法可以正确地级联吗?
谢谢!
最佳答案
This following code works fine with MySQL, but when I try this on derby I get exceptions:
我的猜测是您没有在 MySQL 中使用参照完整性(即不是 InnoDB 引擎),因此没有“触发”约束违规。但是错误就在那里。
实际上,问题在于您应该将 mappedBy
放在双向关联的同一侧,例如在 Tags
上同时为 ManyToMany
(并将其从 Files
中删除):
@Entity
public class Tags implements Serializable {
@ManyToMany(mappedBy = "userTags")
@ForeignKey(name = "USER_TAGS_FILES", inverseName = "USER_FILES_TAGS")
@JoinTable(name = "USERTAGS_FILES", joinColumns = @JoinColumn(name = "TAGS_ID"), inverseJoinColumns = @JoinColumn(name = "FILES_ID"))
public Set<Files> getUserFiles() {
return userFiles;
}
@ManyToMany(mappedBy = "autoTags")
public Set<Files> getAutoFiles() {
return autoFiles;
}
//...
}
文件
变成:
@Entity
public class Files implements Serializable {
@ManyToMany
public Set<Tags> getUserTags() {
return userTags;
}
@ManyToMany
@ForeignKey(name = "AUTO_FILES_TAGS", inverseName = "AUTO_TAGS_FILES")
@JoinTable(name = "AUTOTAGS_FILES", joinColumns = @JoinColumn(name = "FILES_ID"), inverseJoinColumns = @JoinColumn(name = "TAGS_ID"))
public Set<Tags> getAutoTags() {
return autoTags;
}
// ...
}
通过这些更改,以下测试通过( session
在测试方法之外创建):
@Test
public void removeFiles() {
Files files = (Files) session.get(Files.class, 1L);
session.delete(files);
session.flush();
Query q = session.createQuery("from Files f where f.id = :id");
q.setParameter("id", 1l);
Files result = (Files) q.uniqueResult();
assertNull(result);
}
并生成以下查询:
Hibernate: select files0_.id as id100_0_ from Files files0_ where files0_.id=? Hibernate: delete from AUTOTAGS_FILES where FILES_ID=? Hibernate: delete from Files_TAGS where userFiles_id=? Hibernate: delete from Files where id=? Hibernate: select files0_.id as id100_ from Files files0_ where files0_.id=?
使用 Derby 测试。
关于java - derby + hibernate ConstraintViolationException 使用多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3022258/