[jboss-user] [EJB 3.0] - ManyToMany relationship do not work properly
fla83tn
do-not-reply at jboss.com
Tue Nov 20 11:56:06 EST 2007
Hi to all,
I'm working on jboss 4.2.1GA and I'm stuck with a simple ManyToMany relationship..
I have this relation between Users and Sources (of rss feeds - URLs in practice). I followed all tutorial about how to do it and I tried a lot of solutions but I can't figure out why it doesn't work!
Here's the entity class User:
package nc.entities.user;
|
| import javax.persistence.*;
| import java.util.Collection;
| import java.util.ArrayList;
| import nc.entities.source.Source;
|
|
| @Entity(name="User")
| @Table(name="USERS")
| //Named queries expressed the Java Persistence query language
| @NamedQueries(
| { @NamedQuery(
| name="User.findByNickName",
| query="SELECT u FROM User u WHERE u.nick LIKE :nick"
| ),
| @NamedQuery(
| name="User.deleteAll",
| query="DELETE FROM User u"
| ),
| @NamedQuery(
| name="User.selectAll",
| query="SELECT u FROM User u"
| )
|
| }
| )
| public class User {
|
| private int userId;
| private String name;
| private String password;
| private String nick;
| private Collection<Source> sources;
|
| /** Entities must have a public no-arg constructor */
| public User() { }
|
| @Id
| @TableGenerator(name="USER_ID_GENERATOR",
| table="ID_GEN",
| pkColumnName="GEN_KEY",
| valueColumnName="GEN_VALUE",
| pkColumnValue="USER_ID",
| allocationSize=1)
| @GeneratedValue(strategy=GenerationType.TABLE,generator="USER_ID_GENERATOR")
| public int getUserId() { return userId; }
| public String getName() { return name; }
| public String getPassword(){ return password; }
| public String getNick() { return nick; }
|
| public void setUserId(int id) { this.userId=id; }
| public void setName(String name) { this.name=name; }
| public void setPassword(String password){ this.password=password; }
| public void setNick(String nick) { this.nick=nick; }
|
| // N:M bidirectional - TO
| @ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY,mappedBy="users",targetEntity=Source.class)
| public Collection<Source> getSources() { return sources;}
| public void setSources(Collection<Source> sources) { this.sources = sources;}
|
| }
and here's the code of entity Source
package nc.entities.source;
|
|
| import javax.persistence.*;
| import java.util.Collection;
| import java.util.ArrayList;
| import nc.entities.user.User;
| import nc.entities.feed.Feed;
|
| @Entity(name="Source")
| @Table(name="SOURCES")
| @NamedQueries(
| { @NamedQuery(
| name="Source.findByUrl",
| query="SELECT s FROM Source s WHERE s.url LIKE :url"
| ),
| @NamedQuery(
| name="Source.deleteAll",
| query="DELETE FROM Source s"
| )
| }
| )
| public class Source {
|
| private int sourceId;
| private String url;
| private Collection<User> users;
| private Collection<Feed> feeds;
|
| /** Entities must have a public no-arg constructor */
| public Source(){ }
|
| public void setUrl(String url){this.url=url;}
| public void setSourceId(int id){this.sourceId=id;}
|
| @Id
| @TableGenerator(name="SOURCE_ID_GENERATOR",
| table="ID_GEN",
| pkColumnName="GEN_KEY",
| valueColumnName="GEN_VALUE",
| pkColumnValue="SOURCE_ID",
| allocationSize=5)
| @GeneratedValue(strategy=GenerationType.TABLE,generator="SOURCE_ID_GENERATOR")
| public int getSourceId(){return sourceId;}
| public String getUrl() {return url;}
|
| // N:M: bidirectional - FROM
| @ManyToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY, targetEntity=User.class)
| //@JoinTable(name="SOURCE_USER")
| @JoinTable(name = "SOURCE_USER",
| joinColumns = @JoinColumn(name = "SOURCE_ID", referencedColumnName="sourceId"),
| inverseJoinColumns = @JoinColumn(name = "USER_ID", referencedColumnName="userId"))
| public Collection<User> getUsers() { return users; }
| public void setUsers(Collection<User> users) { this.users = users; }
|
| // 1:N unidirectional: FROM
| @OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
| public Collection<Feed> getFeeds() { return feeds; }
| public void setFeeds(Collection<Feed> feeds) { this.feeds = feeds; }
|
| }
The table is SOURCE_USER is created correctly, users and sources are also stored correctly! The function getUsers or getSources works fine if some data are inserted manually in the SOURCE_USER table, but if I perform a setUsers nothing is inserted in that table.
Here's the code of a session bean where I try to insert relationship data:
@Stateless
| @Remote(UserSessionFacade.class)
| @TransactionManagement(TransactionManagementType.CONTAINER)
| public class UserSessionFacadeBean implements UserSessionFacade {
| static Logger logger=Logger.getLogger(UserSessionFacadeBean.class);
| @Resource // Injection using annotations
| private SessionContext sessionContext;
| //@PersistenceContext(type=PersistenceContextType.EXTENDED,unitName="NewsCrawlerPu")
| @PersistenceContext//(unitName="NewsCrawlerPu")
| private EntityManager manager;
|
| @TransactionAttribute(TransactionAttributeType.REQUIRED)
| public void createSources(UserDTO userDTO) {
| if (userDTO == null) { logger.error("UserDTO passed is null!");return; }
| logger.debug("Adding sources to a user - dto passed is:".concat(userDTO.toString()));
| if(userDTO.getId()!=null || userDTO.getNick()!=null ){
| User user=null;
| if(userDTO.getId()!=null)
| user = manager.find(User.class,userDTO.getId());
| else
| user = findUserByNick(userDTO.getNick());
| if(user==null){
| logger.error("User not found in Db..");
| //Abort if user does not exist
| sessionContext.setRollbackOnly();
| }
| else{
| logger.trace("User found in db");
| SourceDTO[] s=userDTO.getSources();
| Collection<User> list;
| Object o=null;
| int length;
| if(s!=null && (length=s.length)!=0){
| for (int i = 0; i < length; i++) {
| logger.trace("for cicle: search for "+s.getUrl());
| Source src = null;
| Query q=manager.createNamedQuery("Source.findByUrl");
| logger.trace("Creating namedQuery...");
| try{
| o=q.setParameter("url",s.getUrl()).getSingleResult();
| }catch(NoResultException e){
| logger.warn("Source "+s.getUrl()+" not found!");
| o=null;
| }catch(NonUniqueResultException e){
| logger.error("No unique result found!");
| o=null;
| }catch(Exception e){
| logger.error("Wrong query: MUST be a SELECT!");
| o=null;
| }
| if(o!=null){
| src=(Source)o;
| logger.debug("Source already present in Db: ");
| logger.debug("checking if user already hold it");
| Collection <User>coll = src.getUsers();
| Iterator<User> iter = coll.iterator();
| boolean found = false;
| while (iter.hasNext() && found==false) {
| User u = iter.next();
| logger.trace("User: "+u.getUserId()+", "+u.getName());
| if (u.getUserId()==user.getUserId())
| found = true;
| }
| list = new ArrayList(coll);
| if (!found) {
| logger.debug("Register user to that Source");
| list.add(user);
| src.setUsers(list);
| manager.merge(src);
| manager.refresh(src);
| } else {
| logger.debug("User already registered to that Url");
| }
| }else{
| logger.debug("New Source (not found in Db): adding user to it");
| src=SourceAssembler.createSource(s);
| list = new ArrayList<User>();
| list.add(user);
| src.setUsers(list);
| manager.persist(src);
| manager.refresh(src);
| }
| }
| }else{
| logger.warn("No source to add...Strange!");
| }
| }
| }else{
| logger.error("Missing user id in the passed DTO or id not valid!");
| }
| }
| .....
| .....
|
Any suggest?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4106479#4106479
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4106479
More information about the jboss-user
mailing list