Hibernate:如何在Annotation的一个连接表中连接三个表? [英] Hibernate: How to Join three 3 tables in one join table in Annotation?

查看:117
本文介绍了Hibernate:如何在Annotation的一个连接表中连接三个表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你能帮我解释一下如何用一个公共连接表连接三张表吗?
我有USER,APPLICATION和ROLE表。
我想让他们的ID加入名为USER_APP_ROLE(user.ID,application.ID,role.ID)的表中。



当我删除应用程序或角色表加入多对多我的代码正在工作。



我已完成以下代码:

User.java

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

私人收藏< Role>角色;

@ManyToMany(targetEntity = Application.class)
@JoinTable(名称= USER_APPLICATION_ROLE,
joinColumns = @ JoinColumn(名称= USER_ID),
inverseJoinColumns = @ JoinColumn(name =APPLICATION_ID))
private Collection< Application>应用;

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

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

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

我得到以下错误:

 休眠:选择seq_role.nextval从双
休眠::从双
休眠选择seq_role.nextval:选择seq_application从双
休眠选择seq_cm_user.nextval。 Hibernate:从双
中选择seq_application.nextval Hibernate:插入CM_USER(EMAIL,FIRST_NAME,LAST_NAME,MIDDLE_NAME,USERNAME,ID)值(?,?,?,?,?,? )
Hibernate:插入CM_ROLE(DESCRIPTION,ID)值(?,?)
Hibernate:插入CM_ROLE(DESCRIPTION,ID)值(?,?)
Hibernate:插入CM_APPLICATION (?,?,?)
Hibernate:插入到CM_APPLICATION(CODE,DESCRIPTION,ID)值(?,?,?)
Hibernate:插入到USER_APPLICATION_ROLE(USER_ID ,APPLICATION_ID)值(?,?)
Hibernate:插入USER_APPLICATION_ROLE(USER_ID,APPLICATION_ID)值(?,?)
线程mainorg.hibernate中的异常。 exception.ConstraintViolationException:在org.hibernate.exception.SQLStateConverter.convert无法执行JDBC批处理更新
(SQLStateConverter.java:96)
在org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java: 66)$在org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275 b $ b)
。在org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
。在有机.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
在org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
在org.hibernate.persister.collection.AbstractCollectionPersister .recreate(AbstractCollectionPersister.java:1179)
在org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)在org.hibernate.engine.ActionQueue.execute
(ActionQueue.java:273 )
在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
在org.hibernate.engine.ActionQueue。在org.hibernate.event.def.AbstractFlushingEventListener.performExecutions executeActions(ActionQueue.java:188)
(AbstractFlushingEventListener.java:321)
在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)
在org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
。在com.hp.gdas.capman.HibernateTest.main(HibernateTest.java:73)

。通过致:java.sql.BatchUpdateException:ORA-01400:无法将NULL插入( SYSTEM, USER_APPLICATION_ROLE ROLE_ID)
在oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
。在oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10657)
处org.hibernate作为org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
。 jdbc.AbstractBatche r.executeBatch(AbstractBatcher.java:268)
... 14 more

谢谢非常多!

解决方案

问题在于您已经定义了与角色和单独关系关系的关系到应用程序。没有任何声明表明任何特定的用户都是 一个角色和一个应用程序的连接。



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



下面是一个映射类 A 的三向连接的示例, B C 使用JPA。请注意,连接表不需要实体。

  @Entity 
public class A {

@JoinTable(名称= a_b_c,
joinColumns = @JoinColumn(名称= A_ID),
inverseJoinColumns = @JoinColumn(名称= C_ID))
@MapKeyJoinColumn (name =b_id)
@ElementCollection
私人地图< B,C> cByB = new HashMap<>();

}

@实体
公共类B {
...
}

@实体
public class C {
...
}


Can you please help me how to join three tables with one common join table? I have USER, APPLICATION, and ROLE tables. And I want thier IDs to be joined in a table named USER_APP_ROLE(user.ID, application.ID, role.ID).

When I remove either Application or Role tables in Join Many to Many my code is working.

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

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

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

Thank you very much!

解决方案

The problem is that you have defined a relationship to roles and a separate relationship to applications. There's no declaration that any specific user is a join of both one role and one application.

When you try to associate with a role, the application is null and visa-versa.

Here's an example of mapping a 3-way join between classes A, B and C using JPA. Note, no entity is required for the join table.

@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 {
    ...
}

这篇关于Hibernate:如何在Annotation的一个连接表中连接三个表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆