简体   繁体   中英

Hibernate Annotatoin - How to Join Three Tables with many to many relationship

  1. I have 3 Entity USER, APPLICATION, and ROLE .

    1. I want there IDs to be joined in a table named USER_APP_ROLE(user_ID, application_ID, role_ID) with many to many relationship between them.
    2. Reason I want this structure is- I have requirement of allowing the user to work on multiple application with multiple roles.
    3. I have done the following codes:

    User.java @ManyToMany (targetEntity=Role.class) @JoinTable(name="USER_APPLICATION_ROLE", joinColumns=@JoinColumn(name="USER_ID"), inverseJoinColumns=@JoinColumn(name="ROLE_ID")) private Collection roles;

      @ManyToMany (targetEntity=Application.class) @JoinTable(name="USER_APPLICATION_ROLE", joinColumns=@JoinColumn(name="USER_ID"), inverseJoinColumns=@JoinColumn(name="APPLICATION_ID")) private Collection<Application> applications; Role.java @ManyToMany(mappedBy="roles", targetEntity=User.class) private Collection<User> users = new ArrayList<User>(); Application.java @ManyToMany(mappedBy="applications", targetEntity=User.class) private Collection<User> users = new ArrayList<User>(); 
    1. When I tried to run the following test:

    user.getRoles().add(role1); user.getRoles().add(role2);

    role1.getUsers().add(user); role1.getUsers().add(user);

    role2.getUsers().add(user); role2.getUsers().add(user);

    user.getApplications().add(app1); user.getApplications().add(app2);

    app1.getUsers().add(user); app2.getUsers().add(user);

    ......

    session.beginTransaction(); session.save(user); session.save(role1); session.save(role2); session.save(app1); session.save(app2);

     I get the following error: Hibernate: select seq_cm_user.nextval from dual Hibernate: select seq_role.nextval from dual Hibernate: select seq_role.nextval from dual Hibernate: select seq_application.nextval from dual Hibernate: select seq_application.nextval from dual Hibernate: insert into CM_USER (EMAIL, FIRST_NAME, LAST_NAME, MIDDLE_NAME, USERNAME, ID) values (?, ?, ?, ?, ?, ?) Hibernate: insert into CM_ROLE (DESCRIPTION, ID) values (?, ?) Hibernate: insert into CM_ROLE (DESCRIPTION, ID) values (?, ?) Hibernate: insert into CM_APPLICATION (CODE, DESCRIPTION, ID) values (?, ?, ?) Hibernate: insert into CM_APPLICATION (CODE, DESCRIPTION, ID) values (?, ?, ?) Hibernate: insert into USER_APPLICATION_ROLE (USER_ID, APPLICATION_ID) values (?, ?) Hibernate: insert into USER_APPLICATION_ROLE (USER_ID, APPLICATION_ID) values (?, ?) Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114) at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109) at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244) at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1179) at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133) at com.hp.gdas.capman.HibernateTest.main(HibernateTest.java:73) Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("SYSTEM"."USER_APPLICATION_ROLE"."ROLE_ID") at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343) at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10657) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) ... 14 more 

    6.I might have doing this in wrong direction.Please help and suggest me any alternative if im totally doing in wrong way.Any help is appreciated.

thanks.

It seems that you want the USER_APPLICATION_ROLE table to contain the assignment of a Role to a User in an Application. But that's not what your mapping does. What it does is use this table to contain the roles of a user (ignoring the application), and also the applications of a user (ignoring the role).

Your mapping is thus wrong. You need to map the USER_APPLICATION_ROLE table as an entity, since it's not a pure join table between two entities. You could name it UserApplicationRole for example. A User would have a OneToMany association with UserApplicationRole. UserApplicationRole would have a ManyToOne association with User, as well as with Role and with Application. And I strongly suggest you to add an automatically generated ID column to this table, just like for all your entities.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM