我正在尝试为学校编写简单的项目,但我遇到了无法解决的问题。我搜索堆栈的解决方案,但没有任何真正的工作。所以问题是:
我有两个用Hibernate创建的实体类(我的数据库是HSQLDB):
@Entity
@Table(name = "Zwierzak")
@NamedQueries({ @NamedQuery(name = "delZwierzak", query = "Delete from Zwierzak z where z.zwierzakId = :zid"),
@NamedQuery(name = "delAll", query = "Delete from Zwierzak"),
@NamedQuery(name = "getAll", query = "from Zwierzak"),
@NamedQuery(name = "getByGatunek", query = "Select z from Zwierzak z where z.gatunek = :g")})
public class Zwierzak {
//Some fields here ...
@OneToMany(fetch = FetchType.EAGER, mappedBy = "chorobaId", cascade = {javax.persistence.CascadeType.ALL}, orphanRemoval = true)
@Cascade({org.hibernate.annotations.CascadeType.ALL})
private Set<Choroba> choroby = new HashSet<Choroba>(0);
//Some methods here ...
第二节课:
@Entity
@Table(name="Choroba")
public class Choroba {
//Some fields here ...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="zwierzakId")
@OnDelete(action = org.hibernate.annotations.OnDeleteAction.CASCADE)
Zwierzak zwierzak;
//Some methods here ...
现在我将一些Zwierzak实体添加到数据库中,并尝试像这样添加Choroba:
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
//Creating and saving Zwierzak (parent) first
Zwierzak z = new Zwierzak();
session.save(z);
//Creating choroba
Choroba ch = new Choroba();
//Setting parent in child class
ch.setZwierzak(z);
//Adding child in parent class
z.getChoroby().add(ch);
//Saving child
session.save(ch);
我仍然有例外。这是来自log的堆栈跟踪:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.673 sec <<< FAILURE!
addZwierzakTest(pl.ug.edu.pl.services.ZwierzakServiceTest) Time elapsed: 0.249 sec <<< ERROR!
org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2975)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3487)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
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:606)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:352)
at com.sun.proxy.$Proxy17.save(Unknown Source)
at pl.ug.edu.pl.services.ZwierzakService.dodajChorobe(ZwierzakService.java:50)
at pl.ug.edu.pl.services.ZwierzakServiceTest.addZwierzakTest(ZwierzakServiceTest.java:45)
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:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
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:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no parent; FK_Q70JGX265MYFNVPD1K5M8ONUD table: CHOROBA
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
... 58 more
我不知道出了什么问题,尝试了很多我认为应该解决这个问题的东西,但它仍然不起作用,我不知道我做错了什么。将不胜感激,提前感谢! :)
编辑:Id是由@Id注释产生的。
答案 0 :(得分:4)
我认为问题是保存操作在提交时间之前不会创建id,因此当您尝试使第二个保存ID不存在时,请在第二次保存之前考虑刷新。
Zwierzak z = new Zwierzak();
session.save(z);
!!!Consider a flush here !!!
session.flush();
//Creating choroba
Choroba ch = new Choroba();
//Setting parent in child class
ch.setZwierzak(z);
//Adding child in parent class
z.getChoroby().add(ch);
//Saving child
session.save(ch);
另外
@OneToMany(fetch = FetchType.EAGER, mappedBy = "chorobaId",
应该是
@OneToMany(fetch = FetchType.EAGER, mappedBy = "zwierzak",
通过引用将包含@ManyToOne的类型的字段进行映射,而不是直接使用id。它应该解决这个问题。
答案 1 :(得分:0)
在我的情况下,更新了@OneToMany集合,删除了一些项目,并添加了新项目。尽管在集合中指定了orphanremoval = true,但hiberhate实际上并没有从数据库中删除条目。 尝试删除拥有实体时抛出异常。
修复是在更新操作期间明确删除数据库中的项目。