Hibernate:如何在注释中将三个 3 表连接到一个连接表中?

Posted

技术标签:

【中文标题】Hibernate:如何在注释中将三个 3 表连接到一个连接表中?【英文标题】:Hibernate: How to Join three 3 tables in one join table in Annotation? 【发布时间】:2011-06-28 16:10:55 【问题描述】:

你能帮我如何用一个普通的连接表连接三个表吗? 我有 USER、APPLICATION 和 ROLE 表。 我希望将他们的 ID 加入一个名为 USER_APP_ROLE(user.ID, application.ID, role.ID) 的表中。

当我在 Join Many to Many 中删除 Application 或 Role 表时,我的代码正在运行。

我做了以下代码:

用户.java

@ManyToMany (targetEntity=Role.class)
@JoinTable(name="USER_APPLICATION_ROLE",
    joinColumns=@JoinColumn(name="USER_ID"),
    inverseJoinColumns=@JoinColumn(name="ROLE_ID"))

private Collection<Role> roles;

@ManyToMany (targetEntity=Application.class)
@JoinTable(name="USER_APPLICATION_ROLE",
    joinColumns=@JoinColumn(name="USER_ID"),
    inverseJoinColumns=@JoinColumn(name="APPLICATION_ID"))
private Collection<Application> applications;

角色.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>();

当我尝试运行以下测试时:

    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);

我收到以下错误:

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

非常感谢!

【问题讨论】:

你能解决这个问题吗? 【参考方案1】:

问题在于您已经定义了与角色的关系以及与应用程序的单独关系。没有声明任何特定用户是一个角色和一个应用程序的加入。

当您尝试与角色关联时,应用程序为空,反之亦然。

下面是一个使用 JPA 在 ABC 类之间映射 3 路连接的示例。注意,连接表不需要实体。

@Entity
public class A 

    @JoinTable(name = "a_b_c",
        joinColumns = @JoinColumn(name = "a_id"),
        inverseJoinColumns = @JoinColumn(name = "c_id"))
    @MapKeyJoinColumn(name = "b_id")
    @ElementCollection
    private Map<B, C> cByB = new HashMap<>();



@Entity
public class B 
    ...


@Entity
public class C 
    ...

【讨论】:

@Synesso,B 和 C 类需要 ManyToMany 关系。我面临这样的错误:线程“main”java.lang.IllegalStateException中的异常:集合元素(多对多)表别名不能为空 这不允许我拥有像 (1,1,1),(1,2,1) 这样的所有可能性。如何实现? @Synesso - 请您在这里指导我:***.com/questions/57311851/… ?

以上是关于Hibernate:如何在注释中将三个 3 表连接到一个连接表中?的主要内容,如果未能解决你的问题,请参考以下文章

hibernate:使用注释的完全连接

如何将表与中间表和附加相关列spring hibernate mvc连接起来

如何使用hibernate标准连接多个表,其中实体关系不是直接的?

Hibernate:如何映射到静态表?

Hibernate 默认模式和表注释

Hibernate Annotation - 如何连接三个具有多对多关系的表