Hello,
I have bi-directional association between parent/child.
Parent can have too many children and I want to add and
remove to "children" (inverse=true) collection without
loading collection.
"children" collection mapped as <bag>. With adding to
collection I have no problem, but when I try to remove
from this collection, collection perform initialization.
Java class:
public class MyObject
{
private Long id;
private MyObject parent;
private Collection< MyObject > children = new
ArrayList< MyObject >();
public MyObject()
{
}
public void addChild( MyObject object )
{
object.parent = this;
children.add( object );
}
public void removeChild( KAObject object )
{
object.parent = null;
children.remove( object ); // initialization of
collection. it is strange, because too many children.
}
}
Database:
table: my_object
fields:
- id
- parent_id
Mapping:
<hibernate-mapping>
<class name="MyObject" table="my_object" >
<id name="id" column="id" type="long">
<generator class="sequence">
<param name="sequence">my_object_seq</param>
</generator>
</id>
<many-to-one name="parent" class="MyObject"
column="parent_id" lazy="no-proxy" cascade="evict"
access="field" />
<bag name="children" inverse="true" lazy="true"
cascade="all-delete-orphan" access="field">
<key column="parent_id" />
<one-to-many class="MyObject" />
</bag>
</class>
I want for example move child to another parent.
MyObject newParent = session.get(MyObject.class, 1);
MyObject child = session.get(MyObject.class, 2);
MyObject oldParent = myObject.getParent();
oldParent.removeChild(child); // initialization of
collection. it is strange, because too many children.
newParent.addChild(child) // no initialization
Why PersistentBag.remove is not implemented like
PersistentBag.add ?
public boolean add(Object object) {
if ( !isOperationQueueEnabled() ) {
write();
return bag.add(object);
}
else {
queueOperation( new SimpleAdd(object) );
return true;
}
}
public boolean remove(Object o) {
initialize( true );
if ( bag.remove( o ) ) {
dirty();
return true;
}
else {
return false;
}
}
I think problem, that interface of
Collection.remove(Object) should return result of remove.
But what aboutm if I never use this result.
I can write own implementation of PersistentBag with
overrided method remove. and use it in User Collection
Type.
public boolean remove( Object o )
{
if ( !isOperationQueueEnabled() )
{
write();
return bag.remove( o );
}
else
{
queueOperation( new SimpleRemove( o ) );
return true; // this result can be wrong
}
}
final class SimpleRemove implements DelayedOperation {
private Object value;
public SimpleRemove(Object value) {
this.value = value;
}
public void operate() {
bag.remove(value);
}
public Object getAddedInstance() {
return null;
}
public Object getOrphan() {
return value;
}
}
In this implementation I should always remember, that
result of Collection.remove(Object) can be wrong and never
use it.
May be anybody know another solution?
Show replies by date