-->
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.  [ 3 posts ] 
Author Message
 Post subject: mapping join table with a view (tries to delete from view)
PostPosted: Fri Jun 08, 2007 12:43 pm 
Expert
Expert

Joined: Wed Apr 06, 2005 5:03 pm
Posts: 273
Location: Salt Lake City, Utah, USA
Hibernate version: 3.2.3

Name and version of the database you are using: MySQL 5

I have a 'document' table that is hierarchical:

Code:
document {
    document_id PK,
    parent_id FK(document),
    ...
}


The way our document tree is set up is with a single 'root' document, with document_id = 1. All other documents are under the root document, in a tree structure.

Because we frequently need to know all descendents or ancestors of a particular document, we maintain a link table:

Code:
document_ancestry_link {
    document_id FK(document),
    ancestor_id FK(document)
}


This table has rows for each document, linking to each of its 'ancestors' (its parent, that parent's parent, ..., the root doc (1)).

This allows us to map associations to a document's 'ancestors' or 'descendents'. Here's the mapping, with annotations, for ancestors, on the Document class:

Code:
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(
        name="document_ancestry_link",
        joinColumns={@JoinColumn(name="document_id")},
        inverseJoinColumns={@JoinColumn(name="ancestor_id")}
        )
    public Set<Document> getAncestors() {
        return this.ancestors;
    }


The children of the root document are important, called a 'collection'. We frequently want to find out what collection a document is in, or run queries by collection.

We are trying to make this simple by creating a view, called 'document_collection', which is essentially a link table from any document to its collection document:

Code:
CREATE OR REPLACE VIEW document_collection AS
SELECT d.document_id as document_id, a.document_id as collection_id
FROM document d
JOIN document_ancestry_link l ON d.document_id = l.document_id
JOIN document a ON l.ancestor_id = a.document_id
WHERE a.parent_id = 1;


I'd like to map this in the Document object, so I have a getCollection() method that returns the collection for any document.

My problem is that no matter how I map it, I can't get Hibernate not to try to delete from the view when I delete a document. Here's what I have currently:

Code:
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinTable(name="document_collection", joinColumns=@JoinColumn(name="document_id"), inverseJoinColumns=@JoinColumn(name="publication_id"))
    public Document getCollection()
    {
        return this.collection;
    }


I can add 'updatable=false, insertable=false' to the @JoinColumn, but that doesn't seem to affect deletes at all. I feel like there needs to be a 'deletable=false' option, which there isn't. Here's the relevant part of the log, with the exception:

Quote:
2007-06-08 08:36:35,365 [main] DEBUG org.hibernate.SQL - delete from document_ancestry_link where document_id=?
2007-06-08 08:36:35,365 [main] DEBUG org.hibernate.SQL - delete from document_collection where document_id=?
2007-06-08 08:36:35,365 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1395, SQLState: HY000
2007-06-08 08:36:35,365 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Can not delete from join view 'servicetest.document_publication'
2007-06-08 08:36:35,365 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: could not delete: [com.blah.Document#5]
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.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2541)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:74)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
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.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.blah.DocumentManager.deleteDocument(DocumentManager.java:1348)
at

...

Caused by: java.sql.SQLException: Can not delete from join view 'document_collection'
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2941)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3249)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1268)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1541)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1455)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1440)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2523)
... 35 more


Notice that Hibernate deletes from document_ancestry_link, because of the ancestors association, which is all that needs to happen, but then it tries to delete from the view, also.

How can I tell Hibernate not to try to delete from the view??

_________________
nathan


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 9:48 am 
Newbie

Joined: Fri Mar 14, 2008 4:20 am
Posts: 17
On Oracle you could implement an INSTEAD OF DELETE-Trigger for your view which just does nothing.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 11, 2008 1:22 pm 
Newbie

Joined: Fri Apr 04, 2008 2:17 pm
Posts: 15
I had this same problem and worked around it the following way

http://forum.hibernate.org/viewtopic.php?t=985505


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.