当前位置: 首页 > 知识库问答 >
问题:

Hibernate saveOrUpdate创建一个对象的两个实例

长孙朝明
2023-03-14

使用saveOrUpdate创建新的ebject时,hibernate将对象存储在数据库中并正确返回。但在方法的同一调用中创建了一个带有一些空列的附加对象。

数据库中的对象如下所示:

id  cause   effect  isInTopTen  propability responsibility  scope   title
312 test    test    0           0           NULL            0       NULL
313 test    test    0           2           CUSTOMER        3       test

这是数据类:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name=HibernateConstants.RISK_TABLE)
public class Risk implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;
    private boolean isInTopTen;
    private String title;
    private String cause;
    private String effect;
    @Enumerated(EnumType.STRING)
    private Responsibility responsibility;
    private int propability;
    private int scope;
    @OneToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE}) 
    private List<Keyword> keywords;
    @OneToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE}) 
    private List<Action> actions;
    @OneToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE}) 
    private List<ProjectRisk> derivedProjectsRisks;
}

这是我将对象存储到数据库的方式:public class DataUtils{private Session Session;private static DataUtils DataUtils;

    private DataUtils() {}

    private void setSession() {
        session = HibernateSessionFactory.getInstance().getCurrentSession();
    }

    public static DataUtils getInstance() {
        if (dataUtils == null) {
            dataUtils = new DataUtils();
        }
        return dataUtils;
    }

    public void storeOne(Object o) {
        setSession();
        Transaction transaction = session.beginTransaction();
        session.saveOrUpdate(o);
        transaction.commit();
    }
}

和我的Hibernate配置:

public class HibernateSessionFactory {
    // Singleton
    private HibernateSessionFactory() {}

    private static SessionFactory sessionFactory;

    public static SessionFactory getInstance() {
        if (sessionFactory==null) {
            final Configuration configuration = new Configuration();
            configuration.configure("hibernate.cfg.xml");
            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        }
        return sessionFactory;
    }
}

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
   "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
   "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
    <!-- DB-Connection -->
      <property name="connection.url">jdbc:jtds:sqlserver://localhost:1433/riskManagement</property>
      <property name="connection.username">riskManagement</property>
      <property name="connection.password">riskManagement</property>
      <property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
      <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
      <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
      <property name="current_session_context_class">thread</property>
      <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>      

      <property name="hibernate.hbm2ddl.auto">update</property>

      <!-- Classes added to persistence -->
      <mapping class="com.encoway.riskManagement.data.Customer" />
      <mapping class="com.encoway.riskManagement.data.Keyword" />
      <mapping class="com.encoway.riskManagement.data.Project" />
      <mapping class="com.encoway.riskManagement.data.ProjectRisk" />
      <mapping class="com.encoway.riskManagement.data.Risk" />
      <mapping class="com.encoway.riskManagement.data.Action" />
   </session-factory>
</hibernate-configuration>

有关此事务的日志信息:

Opening new JDBC connection
Created connection to: jdbc:jtds:sqlserver://localhost:1433/riskManagement, Isolation Level: 2
select sequence_next_hi_value from hibernate_sequences with (updlock, rowlock) where sequence_name = 'KEYWORD'
update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'KEYWORD'
Generated identifier: 4882432, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
committing
Processing flush-time cascades
Dirty checking collections
Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
Listing entities:
com.encoway.riskManagement.data.Keyword{id=4882432, name=abc}
insert into KEYWORD (name, id) values (?, ?)
committed JDBC Connection
HHH000420: Closing un-released batch
Releasing JDBC connection
Released JDBC connection
begin
Obtaining JDBC connection
Obtained JDBC connection
initial autocommit status: false
select sequence_next_hi_value from hibernate_sequences with (updlock, rowlock) where sequence_name = 'RISK'
update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'RISK'
Generated identifier: 4718592, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
Loading entity: [com.encoway.riskManagement.data.Keyword#4882432]
select keyword0_.id as id3_0_, keyword0_.name as name3_0_ from KEYWORD keyword0_ where keyword0_.id=?
Result set row: 0
Result row: EntityKey[com.encoway.riskManagement.data.Keyword#4882432]
Resolving associations for [com.encoway.riskManagement.data.Keyword#4882432]
Done materializing entity [com.encoway.riskManagement.data.Keyword#4882432]
Done entity load
committing
Processing flush-time cascades
Dirty checking collections
Collection found: [com.encoway.riskManagement.data.Risk.actions#4718592], was: [<unreferenced>] (initialized)
Collection found: [com.encoway.riskManagement.data.Risk.derivedProjectsRisks#4718592], was: [<unreferenced>] (initialized)
Collection found: [com.encoway.riskManagement.data.Risk.keywords#4718592], was: [<unreferenced>] (initialized)
Flushed: 1 insertions, 0 updates, 0 deletions to 2 objects
Flushed: 3 (re)creations, 0 updates, 0 removals to 3 collections
Listing entities:
com.encoway.riskManagement.data.Risk{id=4718592, title=null, scope=0, keywords=[com.encoway.riskManagement.data.Keyword#4882432], cause=abc, effect=abc, derivedProjectsRisks=[], isInTopTen=false, propability=0, actions=[], responsibility=null}
com.encoway.riskManagement.data.Keyword{id=4882432, name=abc}
insert into RISK (cause, effect, isInTopTen, propability, responsibility, scope, title, id) values (?, ?, ?, ?, ?, ?, ?, ?)
Inserting collection: [com.encoway.riskManagement.data.Risk.actions#4718592]
Collection was empty
Inserting collection: [com.encoway.riskManagement.data.Risk.derivedProjectsRisks#4718592]
Collection was empty
Inserting collection: [com.encoway.riskManagement.data.Risk.keywords#4718592]
insert into RISK_KEYWORD (RISK_id, keywords_id) values (?, ?)
Done inserting collection: 1 rows inserted
committed JDBC Connection
HHH000420: Closing un-released batch
Releasing JDBC connection
Released JDBC connection
begin
Obtaining JDBC connection
Obtained JDBC connection
initial autocommit status: false
Generated identifier: 4718593, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
committing
Processing flush-time cascades
Dirty checking collections
Collection found: [com.encoway.riskManagement.data.Risk.actions#4718593], was: [<unreferenced>] (initialized)
Collection found: [com.encoway.riskManagement.data.Risk.derivedProjectsRisks#4718593], was: [<unreferenced>] (initialized)
Collection found: [com.encoway.riskManagement.data.Risk.keywords#4718593], was: [<unreferenced>] (initialized)
Flushed: 1 insertions, 1 updates, 0 deletions to 2 objects
Flushed: 3 (re)creations, 0 updates, 0 removals to 3 collections
Listing entities:
com.encoway.riskManagement.data.Risk{id=4718593, title=abc, scope=3, keywords=[com.encoway.riskManagement.data.Keyword#4882432], cause=abc, effect=abc, derivedProjectsRisks=[], isInTopTen=false, propability=2, actions=[], responsibility=CUSTOMER}
com.encoway.riskManagement.data.Keyword{id=4882432, name=abc}
insert into RISK (cause, effect, isInTopTen, propability, responsibility, scope, title, id) values (?, ?, ?, ?, ?, ?, ?, ?)
update KEYWORD set name=? where id=?
Inserting collection: [com.encoway.riskManagement.data.Risk.actions#4718593]
Collection was empty
Inserting collection: [com.encoway.riskManagement.data.Risk.derivedProjectsRisks#4718593]
Collection was empty
Inserting collection: [com.encoway.riskManagement.data.Risk.keywords#4718593]
insert into RISK_KEYWORD (RISK_id, keywords_id) values (?, ?)
Done inserting collection: 1 rows inserted
committed JDBC Connection
HHH000420: Closing un-released batch
Releasing JDBC connection
Released JDBC connection

共有1个答案

卫学真
2023-03-14

正如在一个注释中提到的:“我解决了这个问题。在保存之前,有另一个类调用了session.merge(),这导致了额外的对象。”所以这只是一个单独的bug。

 类似资料:
  • 问题内容: 给定以下类,如何将两个实例中的所有值相互比较? 为此的用例是在显示来自服务器的数据的应用程序中。将数据转换为对象后,便会创建该对象的副本。用户能够编辑各种字段等,从而更改对象之一中的值。 需要将可能已更新的主要对象与该对象的副本进行比较。如果对象相等(所有属性的值都相同),则不会发生任何事情。如果任何一个值都不相等,那么应用程序会将更改提交给服务器。 如代码示例所示,由于未指定值,因此

  • 我对RxJS很陌生,所以如果这个问题已经得到回答,我提前道歉。 我有一个Angular 2应用程序,在其中一个组件中有一个普通对象。我将UI绑定到这个对象。我想做的是能够捕获对这个对象的所有更改,无论它们来自代码还是来自用户更改其中一个字段。 我正在查看可观察对象,但似乎只有通过Emit方法推送新对象时,订阅者才能接收通知。例如,在属性绑定到输入字段的情况下,这将如何工作? 有更好的方法吗? 这是

  • 显然,在示例中,我将它们设置为字符串属性,但实际上它们是其他类型的。 注意:Object1和Object2实际上是从SOAP服务器所需的XML模型生成的类。所以我不能修改它们。 在我的代码中,我必须访问Object1或Object2的'name'属性,这取决于不同的因素。这个点是一个事件处理程序,所以在某一时刻,它捕获一个用Object1调用的事件,而在其他时间,它捕获一个用Object2调用的事

  • 如何创建具有整数和字符串输入类型的?如果我创建一个: 这将是一个类型。如果我将其创建为: 这将是类型。我如何创建一个,它可以接受整数和字符串输入类型?谢谢。

  • 假设我有一个名为的类,并且创建了一个新的空对象: 中的构造函数是: 、和是否等于空? 如果不是,有没有办法让我创建对象,使所有三个实例变量都是?

  • 一个接口: 两个实现bean: -单件bean并标记为 -原型Bean 在Manager类中: 观察:spring创建了和,然后创建了autowires。 预期:由于已经标记为,spring应该只创建这个bean并自动连接它。spring不需要创建的实例。这对性能/功能没有影响,但这看起来像是浪费的实例创建,只会被丢弃。