Jpa delete PreRemove issue

847 views
Skip to first unread message

Ludocwi

unread,
Sep 30, 2010, 6:07:25 PM9/30/10
to play-framework
Hi,
I have a ManyToOne relation issue ... (to be original)
I have 2 entities, Original and Copy, and a ManyToOne relation between
Copy and Original.
A Copy can live independently from a Original.
So when I want to delete a Original, I want to keep the Copy(s).
So There is my code :

@Entity
public class Original extends Model {
...

@PreRemove
public void preRemove() {
for (Copy copy : Copy.findAll()) {
copy.original = null;
copy.save();
}
}
}

@Entity
public class Copy extends Model {
...

@ManyToOne
public Original original;
}

It works but the Hibernate doc says it is forbidden to flush during
@PreRemove.
So how can I do this without calling .save() ? Have I to use
@PreRemove ?

Thx
Ludo

Guillaume Bort

unread,
Oct 1, 2010, 5:38:06 AM10/1/10
to play-fr...@googlegroups.com
Perhaps you can try PostRemove?

> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.
>
>

--
Guillaume Bort, http://guillaume.bort.fr

For anything work-related, use g...@zenexity.fr; for everything else,
write guillau...@gmail.com

Ludocwi

unread,
Oct 1, 2010, 8:02:29 AM10/1/10
to play-framework
Actually, I can't use .save() in any callback methods as it is said
here : "A callback method must not invoke EntityManager or Query
methods!"
http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/listeners.html
(table 6.1)

When I delete a Original entity, I could remove Original reference
from Copy in my controllers before, but I think it is not suitable.
And when I keep calling .save() in @PreRemove, and there is a Cascade
Delete which deletes Original I get a HibernateException : "Flush
during cascade is Dangerous"
> Guillaume Bort,http://guillaume.bort.fr
>
> For anything work-related, use g...@zenexity.fr; for everything else,
> write guillaume.b...@gmail.com

Julien Tournay

unread,
Oct 1, 2010, 8:14:25 AM10/1/10
to play-fr...@googlegroups.com
Can't you simply force hibernate to NOT cascade on delete, so that when you delete an an Original, copy is not deleted ?

jto.
Real Programmers don't need comments-- the code is obvious.

Ludocwi

unread,
Oct 1, 2010, 9:07:35 AM10/1/10
to play-framework
I don't cascade on deleting Original Entity (because I want to keep
Copy) but I cascade on delete Library entity which contains
Original(s) :

@Entity
public class Library extends Model {
...

@OneToMany(mappedBy = "library", cascade = CascadeType.REMOVE )
public Set<Original> originals;

}

So when I delete a Library, I get the HibernateException "Flush
during cascade is Dangerous"...

I don't know if I am understandable ... :s


On 1 oct, 14:14, Julien Tournay <boudhe...@gmail.com> wrote:
> Can't you simply force hibernate to NOT cascade on delete, so that when you
> delete an an Original, copy is not deleted ?
>
> jto.
>
>
>
> On Fri, Oct 1, 2010 at 2:02 PM, Ludocwi <ludoch...@gmail.com> wrote:
> > Actually, I can't use .save() in any callback methods as it is said
> > here : "A callback method must not invoke EntityManager or Query
> > methods!"
>
> >http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/htm...
> > play-framewor...@googlegroups.com<play-framework%2Bunsu...@googlegroups.com>
> > .
> > > > For more options, visit this group athttp://
> > groups.google.com/group/play-framework?hl=en.
>
> > > --
> > > Guillaume Bort,http://guillaume.bort.fr
>
> > > For anything work-related, use g...@zenexity.fr; for everything else,
> > > write guillaume.b...@gmail.com
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "play-framework" group.
> > To post to this group, send email to play-fr...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > play-framewor...@googlegroups.com<play-framework%2Bunsu...@googlegroups.com>
> > .

Julien Tournay

unread,
Oct 1, 2010, 9:34:50 AM10/1/10
to play-fr...@googlegroups.com
Unless I'm missing something (which is likely),
if Hibernate deletes the Copies when an Original is deleted, it means that for some reason, the delete is cascaded.

It's confusing because I don't think Hibernate is supposed to do that by default.
Could you share a minimal Play! app with the problem?

jto

To unsubscribe from this group, send email to play-framewor...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

Ludocwi

unread,
Oct 1, 2010, 9:52:25 AM10/1/10
to play-framework
No no, Hibernate does not delete the Copies when an Original is
deleted. (I want to keep the Copies)
When I delete a Original I just want to do Copy.Original = null before
deleting Original, if not I get the Exception below because Copy is
still pointing to Original : (that's why I try to
for (Copy copy : Copy.findAll()) {
copy.original = null;
copy.save();
}
in a @PreRemove)
Ok I'll try to provide you a Play app

15:49:49,171 ERROR ~ failed batch
15:49:49,172 ERROR ~ Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC
batch update
at
org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:
140)
at
org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:
128)
at
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:
66)
at
org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:
275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:
262)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:
183)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:
324)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:
51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at
org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:
791)
at play.db.jpa.JPABase._delete(JPABase.java:73)
at play.db.jpa.GenericModel.delete(GenericModel.java:197)
at models.FormulaTest.deleteTest(FormulaTest.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:
28)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
76)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at play.test.TestEngine.run(TestEngine.java:124)
at controllers.TestRunner.run(TestRunner.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:
408)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:
403)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:176)
at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:
162)
at play.Invoker$Invocation.run(Invoker.java:187)
at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:142)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:
441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor
$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor
$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
at java.util.concurrent.ThreadPoolExecutor
$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor
$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.BatchUpdateException: failed batch
at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
at
com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:
1723)
at
org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:
70)
at
org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:
268)
... 57 more
> > <play-framework%2Bunsu...@googlegroups.com<play-framework%252Buns...@googlegroups.com>
>
> > > > .
> > > > > > For more options, visit this group athttp://
> > > > groups.google.com/group/play-framework?hl=en.
>
> > > > > --
> > > > > Guillaume Bort,http://guillaume.bort.fr
>
> > > > > For anything work-related, use g...@zenexity.fr; for everything
> > else,
> > > > > write guillaume.b...@gmail.com
>
> > > > --
> > > > You received this message because you are subscribed to the Google
> > Groups
> > > > "play-framework" group.
> > > > To post to this group, send email to play-fr...@googlegroups.com.
> > > > To unsubscribe from this group, send email to
> > > > play-framewor...@googlegroups.com<play-framework%2Bunsu...@googlegroups.com>
> > <play-framework%2Bunsu...@googlegroups.com<play-framework%252Buns...@googlegroups.com>

Julien Tournay

unread,
Oct 1, 2010, 10:15:44 AM10/1/10
to play-fr...@googlegroups.com
Oh ok, sorry, I just misunderstood the whole problem ;)

To unsubscribe from this group, send email to play-framewor...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

Ludocwi

unread,
Oct 1, 2010, 10:43:56 AM10/1/10
to play-framework
I uploaded a play app here : git://github.com/ludochane/Play-jpatest-issue.git
In this app, I created entities which uses @PreRemove or not, and 2
tests.

Thank you

On 1 oct, 16:15, Julien Tournay <boudhe...@gmail.com> wrote:
> Oh ok, sorry, I just misunderstood the whole problem ;)
>
> ...
>
> plus de détails »

Guillaume Bort

unread,
Oct 1, 2010, 11:51:10 AM10/1/10
to play-fr...@googlegroups.com
You should override delete() directly.

> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.
>
>

--
Guillaume Bort, http://guillaume.bort.fr

For anything work-related, use g...@zenexity.fr; for everything else,

write guillau...@gmail.com

Ludocwi

unread,
Oct 1, 2010, 12:35:25 PM10/1/10
to play-framework
If I override delete(), It does not cascade well. I will look into
that more deeply.
Thx for the help

On 1 oct, 17:51, Guillaume Bort <guillaume.b...@gmail.com> wrote:
> You should override delete() directly.
>
> ...
>
> plus de détails »

Preslav Rachev

unread,
Jul 23, 2014, 5:40:52 AM7/23/14
to play-fr...@googlegroups.com
Amazing! Almost four years later, I ended up having exactly the same problem. Now, I am struggling to find a solution. Have you figured something out in the meantime?

Thanks,
Preslav
> > .
> > > > For more options, visit this group athttp://
> > groups.google.com/group/play-framework?hl=en.
>
> > > --
> > > Guillaume Bort,http://guillaume.bort.fr
>
> > > For anything work-related, use g...@zenexity.fr; for everything else,
> > > write guillaume.b...@gmail.com
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "play-framework" group.
> > To post to this group, send email to play-fr...@googlegroups.com.
> > To unsubscribe from this group, send email to
Reply all
Reply to author
Forward
0 new messages