Question

I'm trying to write simple project for school, but I have a problem which can't solve. I searched stack for solution, but nothing really works. So the problem:

I have two entity classes created with Hibernate (my db is 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 ...

And second class:

@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 ...

Now I'm adding some Zwierzak entities to database, and try to add Choroba like that:

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

And I'm still getting exceptions. Here is stack trace from 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

I have no idea what is wrong, tried many things which I found that supposed to solve this problem, but still it doesn't work, I don't know where I do something wrong. Will be grateful for little help, thanks in advance! :)

EDIT: Id's are generated by @Id annotation of course.

Was it helpful?

Solution

I think the problem is the save operation does not create the id until the commit time, so when you are trying to make the second save id is not present, consider flush before the second save.

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

Also

@OneToMany(fetch = FetchType.EAGER, mappedBy = "chorobaId", 

It should be

@OneToMany(fetch = FetchType.EAGER, mappedBy = "zwierzak",

Mapped by refer to the field of the type that will contain the @ManyToOne, not directly the id. It should fix the issue.

OTHER TIPS

In my case the @OneToMany collection was updated, some items were removed, and new added. Even though orphanremoval=true was specified on the collection, hiberhate did not actually removed the entries from the database. The exception was thrown at the attempt to delete the owning entity.

The fix was to explicitely delete the items from the DB during the update operation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top