在休眠中的多对多映射中仅插入一个表

Posted

技术标签:

【中文标题】在休眠中的多对多映射中仅插入一个表【英文标题】:Insert into only one table in many-to-many mapping in hibernate 【发布时间】:2017-02-12 04:20:40 【问题描述】:

我有两个表 A 和 B。表 B 已经有数据。我不想将数据插入表 B,而只想插入表 A。 A表的一行对应B表的多行,B表的一行对应A表的多行。 我也想将数据插入到他们的关系表 A_B 中。 我怎样才能做到这一点?

【问题讨论】:

Java 代码可能工作 当然java代码必须工作。但是如何? 向我们展示您的尝试,也许我们可以提供帮助 你能给我看一个多对多映射的例子吗?我只能将数据插入到一个表中? 如何阅读文档:docs.jboss.org/hibernate/orm/5.2/userguide/html_single/…,告诉我们您已经尝试过什么但不起作用?特别看一下“示例 134。带链接实体的双向多对多” 【参考方案1】:

这是我的 ParcelTracking 课程:

private int tracking_ID;
private Date update_DateTime;
private Set<TrackingStatus> trackingStatus;
private String comments; 
// getter,setter and constructor

TrackingStatus 类:

private int trackingStatus_ID;
private String trackingStatus_Desc;
private String comments;
private ParcelTracking parcelTracking;
//Getter, setter and constructor

parceltracking.hbm.xml:

<class name = "org.trackmodel.ParcelTracking" table = "parceltracking">
  <id name = "tracking_ID" column = "Tracking_ID">
  </id>
  <property name = "update_DateTime" column = "Update_DateTime"></property>
  <property name = "comments" column = "Comments"></property>
  <set name = "trackingStatus" table = "parcel_status" cascade = "none" >
     <key column = "Tracking_ID"></key>
     <many-to-many class = "org.trackmodel.TrackingStatus" column = "TrackingStatus_ID"></many-to-many>
  </set>
</class>

trackingstatus.hbm.xml:

 <class name = "org.trackmodel.TrackingStatus" table = "trackingstatus">
    <id name = "trackingStatus_ID" column = "TrackingStatus_ID">
    </id>
    <property name = "trackingStatus_Desc" column = "TrackingStatus_Desc"></property>
    <property name = "comments" column = "Comments"></property>
    <join table = "parcel_status" inverse = "true">
      <key column = "TrackingStatus_ID"></key>
      <many-to-one name = "parcelTracking" class = "org.trackmodel.ParcelTracking" column = "Tracking_ID"/>
    </join>
 </class>

这里我使用 RandomCode 生成器类生成 tracking_ID:

private static final int MAX = 99999999;
private static final int MIN = 11111111;

public int generateCode()

    Random random = new Random();
    int code = random.nextInt(MAX-MIN+1)+MIN;
    return code;


我已经在 trackingstatus 表中有很多数据,TrackingStatus_ID 从 20 开始。我不想在将数据插入到 parceltracking 表时将数据插入其中。parceltracking 的一行对应于 trackingstatus 表中的行数。

当我尝试运行如下代码时:

测试类:

    Set<TrackingStatus> statuses = new HashSet<TrackingStatus>();

    RandomCode randomCode = new RandomCode();

    SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();

    Session session = sessionFactory.getCurrentSession();

    session.beginTransaction();

    int trackingCode = randomCode.generateCode();

    ParcelTracking parcelTracking = new ParcelTracking();
    parcelTracking.setTracking_ID(trackingCode);
    parcelTracking.setComments("NO COMMENT PLEASE");
    parcelTracking.setUpdate_DateTime(new Date());

    TrackingStatus trackingStatus = session.get(TrackingStatus.class,22);
    session.setReadOnly(trackingStatus, true);
    statuses.add(trackingStatus);
    parcelTracking.setTrackingStatus(statuses);

    session.saveOrUpdate(parcelTracking);
    session.getTransaction().commit();
    session.close();

我收到以下错误:

 org.hibernate.exception.GenericJDBCException: could not execute statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2921)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3421)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:468)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3135)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2352)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
at org.tracktest.TestClass.main(TestClass.java:44)
Caused by: java.sql.SQLException: Field 'TrackingStatus_ID' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 18 more

如何在不插入 trackingstatus 表的情况下将数据插入 parceltracking 表? 两个表之间的关系必须是一对多的。

【讨论】:

您应该编辑您的问题,而不是为您的问题添加“答案”。 您是否查看过:***.com/questions/21244110/…?

以上是关于在休眠中的多对多映射中仅插入一个表的主要内容,如果未能解决你的问题,请参考以下文章

没有集合的Hibernate中的多对多映射

ORM表多对多的操作

休眠查询以匹配映射实体集合与给定集合中的至少一个元素,多对多关系

JPA中的多对多双向映射

Spring Boot 中的多对多映射问题

休眠双向多对多映射建议!