These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: self referencing many-to-many collection mapping
PostPosted: Mon Mar 10, 2008 11:10 am 
Newbie

Joined: Mon Mar 10, 2008 10:06 am
Posts: 4
Hi to all!

Just got a delete problem with collection mapping of a self referencing entity. For the many-to-many relationship we are using a database view called 'virtual_dir_map' as the middle table. We are using this view to hide some complex parent-child relationships.

If I delete a 'Directory' object, Hibernate try to delete the corrosponding entry in the view too. Since the the view is not updatable, I get an Exception. Is there a way to set the 'childDirectories' collection or the underlying view to readonly? Or is there another way to avoid the update access to a view?

Thanks in advance!

regards NewTee


Hibernate version:
Hibernate-Version: 3.2.4.sp1


Mapping documents:
Code:
<subclass name="com.basix.hibernate.mappings.Directory" extends="com.basix.hibernate.mappings.AbstractFile" discriminator-value="D">
...
   <set name="childDirectories" table="virtual_dir_map" cascade="none" optimistic-lock="false">
      <key column="parent_id" />
      <many-to-many column="child_id" class="com.basix.hibernate.mappings.Directory"/>
   </set>
</subclass>



Name and version of the database you are using:
MySQL 5.0.41 InnoDB Tables


The generated SQL (show_sql=true):
Hibernate: delete from virtual_dir_map where parent_id=?


Full stack trace of any exception that occurs:
    org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:92)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:87)
    at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:222)
    at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1030)
    at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.springframework.orm.hibernate3.HibernateTemplate$28.doInHibernate(HibernateTemplate.java:837)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
    at org.springframework.orm.hibernate3.HibernateTemplate.flush(HibernateTemplate.java:835)
    at com.basix.hibernate.daos.GenericDAO.delete(GenericDAO.java:81)
    at com.basix.services.PersistenceService.delete(PersistenceService.java:69)
    at com.basix.remote.webdav.DataBaseFileSystem.removeObject(DataBaseFileSystem.java:252)
    at com.basix.remote.webdav.DataBaseFileSystem.removeObject(DataBaseFileSystem.java:240)
    at com.basix.remote.webdav.WebdavServlet.doDelete(WebdavServlet.java:977)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:716)
    at com.basix.remote.webdav.WebdavServlet.service(WebdavServlet.java:2455)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:525)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
    at java.lang.Thread.run(Thread.java:619)


    Caused by: java.sql.BatchUpdateException: The target table virtual_dir_map of the DELETE is not updatable
    at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1237)
    at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:936)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
    ... 41 more


Top
 Profile  
 
 Post subject: Re: self referencing many-to-many collection mapping
PostPosted: Mon Mar 10, 2008 11:57 am 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
You could write a custom delete for it with <sql-delete ...> and <sql-delete-all ...>


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 1:59 pm 
Newbie

Joined: Mon Mar 10, 2008 10:06 am
Posts: 4
Thanks for your help farzad,

now I have checked this custom delete:

Code:
<set name="childDirectories" table="virtual_dir_map" cascade="all">
   <key column="parent_id"/>
   <many-to-many column="child_id" class="com.basix.hibernate.mappings.Directory"/>
   <sql-delete>DELETE FROM files d WHERE d.id=? AND d.discriminator='D'</sql-delete>
</set>

But for some reason my mapping ignores it and uses this:

Code:
Hibernate: delete from virtual_file_map where parent_id=?

and so still try to delete the view entry.

Is there anything which I've done wrong? Thanks for hints ...


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 2:12 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
NewTee wrote:
Is there anything which I've done wrong? Thanks for hints ...


I would say change your mapping in way that it is wrong and see if hibernate is picking this file up at all. I did a small test and it worked fine. There is only one mistake in your sql and that is it has only one parameter and Hibernate will try to set two parameters in the sql (it's a many-to-many so there is two sides). However, you should get an exception for that.




Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 8:23 pm 
Newbie

Joined: Mon Mar 10, 2008 10:06 am
Posts: 4
Thanks again for the hints.

After I dig through the manuals, my impression is that the sql-delete tag is for the custom control of the delete process of the objects within the collection.

From what i understand, it gives no control over the lookup table itself. After stepping through a many-to-many delete process, we see that there is a delete attempt to the lookup table first. After that, the framework is deleting the desired instance.

Since our lookup table is a non updatable view, Hibernate can't process the desired delete command and throws a BatchUpdateException. This seems to be before the custom delete command can be executed.

Is there any chance to avoid the delete access to the lookup table? Thanks for all ideas ...


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 8:26 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
I am wondering if this is a difference between hibernate 3.2.4 and 3.2.5 because my test uses 3.2.5 and it only executes my delete sql and nothing else. After all, it doesn't make much sense to have a combination of customized and tool delete commands.


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 11, 2008 3:45 pm 
Newbie

Joined: Mon Mar 10, 2008 10:06 am
Posts: 4
We finally using a quick workaround for the delete problem.

We are deleting the 'Directory' objects by DML-style operations now and in this way we bypass the control of the Hibernate session. That's not a very clean solution, but it worked ;-)

regards NewTee


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.