-->
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.  [ 2 posts ] 
Author Message
 Post subject: Error with when removing from set annotated with @ManyToAny
PostPosted: Thu Jun 14, 2012 2:25 pm 
Newbie

Joined: Thu Jun 14, 2012 2:15 pm
Posts: 2
Hello, I've been experiencing an interesting issue in my application relating to removing an entity from a collection where there is a ManyToAny mapping from the entity that contains the collection to the interface that defines the members in the collection.

Consider the following mapping from the class "Group" for a set of "GroupMember"s:

Code:
public class Group {
    ...
    @ManyToAny(metaDef = GroupMember.TYPE_NAME, metaColumn = @Column(name = "member_type"), fetch = FetchType.LAZY)
    @JoinTable(name = "GroupMembership",
        joinColumns = @JoinColumn(name = "group_id"),
        inverseJoinColumns = @JoinColumn(name = "member_id")
    )
    private Set<GroupMember> members;

    ...
}


The AnyMetaDef for the mapping is defined separately:
Code:
    @AnyMetaDef(
        name = GroupMember.TYPE_NAME,
        idType = "long",
        metaType = "string",
        metaValues = {
            @MetaValue(value = SomeType1.TYPE_NAME, targetEntity = SomeType1.class),
            ...
        }
    )


There is also a GroupMembership table that looks like this:
Code:
CREATE TABLE GroupMembership (
    group_id bigint NOT NULL,
    member_id bigint NOT NULL,
    member_type varchar(128) NOT NULL,

    CONSTRAINT GroupMembership_PK PRIMARY KEY (group_id, member_id, member_type)
);


group_id is foreign key'ed to the Group table and member_id is foreign key'ed to a GroupMember table.


If multiple items (GroupMembers) are added to the "members" set in "Group," and then one is removed, the following error is encountered:

[org.hibernate.SQL] delete from GroupMembership where group_id=? and member_id=?
[o.h.type.descriptor.sql.BasicBinder] binding parameter [1] as [BIGINT] - 15
[o.h.type.descriptor.sql.BasicBinder] binding parameter [3] as [BIGINT] - 20
[o.h.util.JDBCExceptionReporter] Parameter index out of range (3 > number of parameters, which is 2).

[o.h.e.d.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: could not delete collection rows: [some.package.name.Group.members#15]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.persister.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:1352) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.action.CollectionUpdateAction.execute(CollectionUpdateAction.java:84) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:187) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) ~[hibernate-core.jar:3.6.0.Final]
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) [hibernate-core.jar:3.6.0.Final]
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) [hibernate-core.jar:3.6.0.Final]
at sun.reflect.GeneratedMethodAccessor79.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_21]
at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_21]

It seems that the correct delete sql is generated: delete from GroupMembership where group_id=? and member_id=?

However, the binding does not appear to be functioning properly. Tracing through the hibernate code, I noticed in AbstractCollectionPersister.deleteRows() that initially the key ("group_id" in this case) is written to the prepared statement for the deletion in writeKey(). Subsequently, the location of the next parameter to write to the prepared statement is incremented, which is correct. Next, Hibernate goes to write the member_id element to the prepared statement in writeElementToWhere(). Interestingly, the counter is incremented again before the element is written to the prepared statement, thus causing the error.

Does anyone see any issues with what I am doing or does this seem to be a bug in Hibernate? I feel that if my mapping is invalid, then Hibernate should detect the invalid state instead of trying to create an invalid prepared statement.


Top
 Profile  
 
 Post subject: Re: Error with when removing from set annotated with @ManyToAny
PostPosted: Mon Jun 18, 2012 10:20 am 
Newbie

Joined: Thu Jun 14, 2012 2:15 pm
Posts: 2
*bump*


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