tags:

views:

2557

answers:

3

i have many to many relation ship between two table and jenerate new join table in hibernate now how can i insert record in join table by updatation of both table say two table are tbluser and tbldomain i have to insert record in tbluserdomainrelation from both side(that is from tbluser and tbldomain)

at present i can insert record in join table only when i save or update tbluser but i want record to be inserted when i update relationship in domain table also so plese help

in user.class i have written @ManyToMany(targetEntity = VirtualDomain.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER)

@JoinTable(name = "tblUserDomainRel", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = @JoinColumn(name = "domainid"))

public Set getVirtualdomainset() { return virtualdomainset; }

public void setVirtualdomainset(Set virtualdomainset) { this.virtualdomainset = virtualdomainset; }

while in domain table i have entry

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER, mappedBy = "virtualdomainset", targetEntity = User.class)

public Set getUserset() { return userset; }

public void setUserset(Set userset) { this.userset = userset; }

A: 

How do your classes look like ?

I suppose you have a class Domain and a class User. In the Domain class, suppose you have a Users collection. Add a User object to the Users collection, and call SaveOrUpdate on the Domain object. Also make sure that you've specified the correct cascading option (for instance cascading="save-update".

That 's a bit the big picture. We need more detailed information on what is not working.

Frederik Gheysels
in domain bean i have mapping @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER, mappedBy = "virtualdomainset", targetEntity = User.class) public Set<User> getUserset() { return userset; }in user bean i have mapping @ManyToMany(targetEntity = VirtualDomain.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER) @JoinTable(name = "tblUserDomainRel", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = @JoinColumn(name = "domainid")) public Set<VirtualDomain> getVirtualdomainset() { return virtualdomainset; }
lakhaman
there is setter method in both class but i have not included bacause of size limit.i can insert correctly by calling save or update method of user but i can't insert record by calling save or update method of domain table.so how can i achieve that.
lakhaman
You can edit your question in order to provide more details. That's a lot more readable as well. :)
Frederik Gheysels
A: 

You have made User class the owner of the relationship. If you want to go the other way then you need to switch their mapping so that Domaintable has the @JoinTable. Or you have to manually force it by using @PrePersist or @PreUpdate on Domaintable to forcefully call the update on the User which would insert the row into the join table. I am sure there are other ways to accomplish it, but those are the two that come to mind.

@PreUpdate example :

@EntityListeners( Domaintable.class )
@Entity
public class Domaintable
{

User  user;

....

@PreUpdate
public void onPreUpdate( DomainTable domainTable )
{
   if( domainTable.getUser() != null )
   {
       entitymanager.update( domainTable.getUser() );
    }
}

....

}
ccclark
how can i use prePersist annotation please provide me some idea what value i have to assign in this tag
lakhaman
Updated the post
ccclark
+1  A: 

I suspect you may be falling at the first hurdle:

As has been previously stated, Hibernate will update the object that you call update() on and then cascade down to any subsequent objects that require updating, following the rules you specify in the @Cascade attribute.

The problem is that your User class owns the relationship and adding a User object to the VirtualDomain.userset collection does not alter the User object in any way. Thus even with a cascade, Hibernate will not update the User object as it doesn't think that it has to.

Instead, when you add an object to the VirtualDomain.userset collection, ensure that the VirtualDomain is added to the User.virtualdomainset collection as well.

// given a VirtualDomain object
VirtualDomain domain = getSession().load( VirtualDomain.class, 1234 );

// and a User object
User user = getSession().load( User.class, 5678 );

// add the User to the VirtualDomain
domain.getUserset().add( user );
// but also add the VirtualDomain to the user
user.getVirtualdomainset().add( domain );

// update the VirtualDomain and the Cascade settings will also update the User
getSession().update( domain );

In cases like this I find it useful to provide a helper method for adding objects to collections, rather than using direct access to the collections themselves. e.g.

public class VirtualDomain {

    Set userset;

   /* snip... */

    public void addUser( User user ) {
        getUserset().add( user );
        user.getVirtualdomainset().add( this );
    }
}

Although it's worth remembering the advice of the Hibernate fore-fathers:

"In a real system, you may not have a many-to-many association. Our experience is that there is almost always other information that must be attached to each link... the best way... is via an intermediate assocation class." (Java Persistence With Hibernate, p. 297/298 , ISBN 1-932394-88-5)

Luke