You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

org.hibernate.Session更新方法失效,求助排查原因及事务关联问题

Hibernate Session的update/merge/saveOrUpdate无更新且无异常问题排查

使用org.hibernate.Session的update、merge、saveOrUpdate方法时,数据库未发生更新,且无任何异常抛出。

问题代码(update方法)

@Override
public void update(Domain domain) {
    
    // 创建SessionFactory
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

    // 获取Session
    Session session = sessionFactory.openSession();
    
    // 此处返回false
    boolean contains = session.contains((LogItem)domain);
    
    // 尝试过以下所有方法,均无效
    //session.update((LogItem)domain);
    //session.update( ((LogItem)domain).getClass().getName(), (LogItem)domain );
    //session.merge( (LogItem)domain );
    //session.merge( ((LogItem)domain).getClass().getName(), (LogItem)domain );
    //session.saveOrUpdate( (LogItem)domain );
    session.saveOrUpdate( ((LogItem)domain).getClass().getName(), (LogItem)domain );

    // 关闭Session
    session.close();
            
}

正常工作的save和read方法

create方法

public Serializable create(Domain domain) throws NamingException, SQLException {
    
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    
    session.save(domain);

    session.close();
    
    return domain;
}

read方法

public Domain read(long id) {
    
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    
    LogItem logItem = session.get( LogItem.class, id );

    session.close();
    
    return logItem;
}

Hibernate配置文件(hibernate.cfg.xml)

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <!-- 数据库连接配置 -->
    <property name="hibernate.connection.datasource">jdbc/CRUDS_MySQL_Data_Source</property>
    <!-- JDBC连接池大小 -->
    <property name="connection.pool_size">1</property>
    <!-- SQL方言 -->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- 打印SQL语句 -->
    <property name="hibernate.show_sql">true</property>
    
    <!-- 启用JTA集成 -->
    <property name="hibernate.transaction.jta.platform">
      org.hibernate.engine.transaction.jta.platform.internal.WebLogicJtaPlatform
    </property> 
        
    <!-- 实体映射文件 -->
    <mapping resource="com/mycompany/cruds/domain/LogItem.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

Hibernate依赖信息

[INFO] com.mycompany.cruds:app:ear:1.0.2-SNAPSHOT
[INFO] +- com.mycompany.cruds:server:ejb:1.0.2-SNAPSHOT:compile
[INFO] |  +- org.hibernate:hibernate-core:jar:5.4.23.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.4.1.Final:compile
[INFO] |  |  +- javax.persistence:javax.persistence-api:jar:2.2:compile
[INFO] |  |  +- org.javassist:javassist:jar:3.24.0-GA:compile
[INFO] |  |  +- net.bytebuddy:byte-buddy:jar:1.10.17:compile
[INFO] |  |  +- antlr:antlr:jar:2.7.7:compile
[INFO] |  |  +- org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:jar:1.1.1.Final:compile
[INFO] |  |  +- org.jboss:jandex:jar:2.1.3.Final:compile
[INFO] |  |  +- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] |  |  +- javax.activation:javax.activation-api:jar:1.2.0:compile
[INFO] |  |  +- org.dom4j:dom4j:jar:2.1.3:compile
[INFO] |  |  +- org.hibernate.common:hibernate-commons-annotations:jar:5.1.2.Final:compile
[INFO] |  |  +- javax.xml.bind:jaxb-api:jar:2.3.1:compile
[INFO] |  |  \- org.glassfish.jaxb:jaxb-runtime:jar:2.3.1:compile
[INFO] |  |     +- org.glassfish.jaxb:txw2:jar:2.3.1:compile
[INFO] |  |     +- com.sun.istack:istack-commons-runtime:jar:3.0.7:compile
[INFO] |  |     +- org.jvnet.staxex:stax-ex:jar:1.8:compile
[INFO] |  |     \- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.15:compile
[INFO] |  \- com.mycompany.cruds:interface:jar:1.0.2-SNAPSHOT:compile
[INFO] |     \- com.mycompany.cruds:domain:jar:1.0.2-SNAPSHOT:compile
[INFO] |        \- mysql:mysql-connector-java:jar:5.1.6:compile
[INFO] +- com.mycompany.cruds:facade:war:1.0.2-SNAPSHOT:compile
[INFO] \- com.mycompany.cruds:web-client:war:1.0.2-SNAPSHOT:compile

HibernateUtil工具类

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // 从hibernate.cfg.xml创建SessionFactory
            return new Configuration().configure().buildSessionFactory();
        }
        catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
        // 关闭缓存和连接池
        getSessionFactory().close();
    }

}

可正常工作的EntityManager实现

@PersistenceContext(unitName = "your_persistence_unit_name")
private EntityManager em;

public void update(Domain domain) {
    
     em.merge(domain);

}

补充:调用链与容器事务配置

DomainHibernateDaoBean(包含所有CRUD方法)

public class DomainHibernateDaoBean {
    
    public Serializable create(Domain domain) throws Exception { ... }

    public Domain read(long id) throws Exception { ... }
    
    public void update(Domain domain) throws Exception { ... }
} 

CrudsTransactionSessionBean(容器管理事务)

import javax.ejb.SessionContext;

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class CrudsTransactionSessionBean implements CrudSessionLocal {

    private DomainHibernateDaoBean domainHibernateDaoBean = new DomainHibernateDaoBean();       
    private boolean throwException;

    @Resource
    private SessionContext sessionContext;

    public CrudsTransactionSessionBean() {
        super();
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void update(Domain domain) throws Exception {
        try {
             domainHibernateDaoBean.update(domain);
          
            if (throwException) {
                throw new Exception("Mockup exception");
            }
        } catch (Exception e) {
            sessionContext.setRollbackOnly();
            throw e;
        }
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public Serializable create(Domain domain) throws Exception {
        try {
            Serializable serializableTemp = domainHibernateDaoBean.create(domain);

            if (throwException) {
                throw new Exception("Mockup exception");
            }
            return serializableTemp;
        } catch (Exception e) {
            sessionContext.setRollbackOnly();
            throw e; 
        }
    }

    @Override
    public Domain read(long id) throws Exception {
        try {
            Domain searchResult = domainHibernateDaoBean.read(id);
            if (throwException) {
                throw new Exception("Mockup exception");
            }
            return searchResult;
        } catch (Exception e) {
            sessionContext.setRollbackOnly();
            throw e;
        }
    }
}

persistence.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="your_persistence_unit_name" transaction-type="JTA">
        <jta-data-source>jdbc/CRUDS_MySQL_Data_Source</jta-data-source>
        <class>com.mycompany.cruds.domain.LogItem</class>
        <class>com.mycompany.cruds.domain.Domain</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

疑问与诉求

原本认为容器事务与HibernateUtil获取的事务是同一事务,但现在对此存疑。设置throwException=true时,create操作会被回滚,这让我疑惑:sessionContext.setRollbackOnly()是否会回滚HibernateUtil的事务?恳请帮忙排查Session更新失效的原因,以及容器事务与Hibernate事务的关联问题。

内容的提问来源于stack exchange,提问作者user2902165

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:01:14