java - @事务: Is there a way that hibernate can persist child transacttion when parent fails

标签 java spring hibernate spring-mvc transactional

我是 Spring-Hibernate 的新手,我的问题是:事务未将数据保存在表中。但也不会抛出任何异常。从行

Long id = logTransactionFileUpload(fileMetdataBean);

在函数“logClientFile”(在“事务”注释类/服务类中,如下所列)中,我看到返回的 ID,但数据未显示在表中。 .

F发现是:这是嵌套事务,并被回滚,因为父级在 JobRunnerServiceImpl 类中的“msgProducer.send( message, jmsConnectInfo )”中出现异常,在 SubmitJob 方法中 - 意味着在数据库插入之后。 当父级失败时, hibernate 是否可以保留子级事务?

我并不怀疑我的 spring/hibernate 配置,因为其他部分的保存工作正常。只有这一部分是问题所在。

仅供引用:

如果我打开(在 DAO impl 类中,如下所列)

 //getCurrentSession().flush();
//getCurrentSession().getTransaction().commit();

然后数据就会显示在表中。但是当使用 @transactional 时,这个提交和刷新不应该出现。

我的@Transactional注释类:

    @Service("jobRunnerService")
    @Transactional
    public class JobRunnerServiceImpl implements JobRunnerService
    {
        private static final Logger LOG = LoggerFactory.getLogger( MethodHandles.lookup().lookupClass() );



        @Autowired
        @Qualifier("fileLoggerDao")
        private IFileLoggerDAO fileLoggerDAO;

        @Autowired
        @Qualifier("fileMetaDataDao")
        private IGenericDAO<FileMetaDataBean,Long> fileMetaDataDAO;



        public void submitJob(String serviceName, String filePath, long clientId, long layoutId, String audienceId,
                boolean isCA) 
        {

            Map<String, String> parameters = new HashMap<String, String>();

            try
            {
                ..... doing something............

                LOG.info( "Logging file information in FILE_META_DATA table... " );
                String loggedFile = logClientFile( fileName, FACEBOOK_FILE_TYPE, fileExt, clientId, tpList );

               ..... doing something............


                LOG.info( " Submitting job to JMS Q...." );
                msgProducer.send( message, jmsConnectInfo );    

                //test code for the receiver to see if sent messages are received by receiver
                //WildFlyJmsQueueReceive receiver = new WildFlyJmsQueueReceive();
                //receiver.receiveMessagesFromQueue();

            }
            catch ( Exception e )
            {
                String msg = "Error in JobRunnerServiceImpl.submitJob";
                LOG.error(msg,e);
                throw new RuntimeException(msg,e);
            }

        }



        private String logClientFile( String fileName, String fileType, String fileExt, long clientId, List<ToolkitPropertyBean> tpList )        
        {
            ApplicationEnvironment enviro;

            try
            {
                ..... doing something............


                //insert record in FILE_META_DATA table
                FileMetaDataBean fileMetdataBean = new FileMetaDataBean(fileId, new Long(fileTypeID), fileName, fbFilePickUpDir +java.nio.file.FileSystems.getDefault().getSeparator()+ currentFile.getName(), receivedDate,new Long( FileUtilities.getRecordCount( currentFile ) ).longValue(), clientId);
                Long id = logTransactionFileUpload(fileMetdataBean);
                return null;
            }
            catch ( Exception e )
            {
                String msg = "Inside JobRunnerServiceImpl.logClientFile  - Unable to log client file";
                LOG.error(msg,e);
                throw new RuntimeException(msg,e);
            }

        }

        private Long logTransactionFileUpload(FileMetaDataBean bean)
        {
            return (Long)fileMetaDataDAO.save(bean);
        }


    }

我的 bean :

    @Entity
    @Table(name="FILE_META_DATA", schema = "OAP_META_OWNER", uniqueConstraints = {
            @UniqueConstraint(columnNames = "file_meta_data_id"),
             })
    //@SequenceGenerator(name="file_meta_seq", sequenceName="file_meta_seq")
    public class FileMetaDataBean implements Serializable
    {

        private long fileMetaDataId;
        private Long fileType;
        private String fileName;
        private String originaFileName;
        private Date receivedDt;
        private Long recordCount;
        private Long clientId;

        public FileMetaDataBean(){}

        public FileMetaDataBean( long fileMetaDataId, Long fileType, String fileName, String originaFileName, Date receivedDt,
                long recordCount, long clientId )
        {
            super();
            this.fileMetaDataId = fileMetaDataId;
            this.fileType = fileType;
            this.fileName = fileName;
            this.originaFileName = originaFileName;
            this.receivedDt = receivedDt;
            this.recordCount = recordCount;
            this.clientId = clientId;
        }

        @Id
    //  @GeneratedValue(strategy = GenerationType.AUTO, generator = "file_meta_seq")
        @Column(name = "file_meta_data_id", unique = true, nullable = false)
        public long getFileMetaDataId()
        {
            return fileMetaDataId;
        }

        public void setFileMetaDataId( long fileMetaDataId )
        {
            this.fileMetaDataId = fileMetaDataId;
        }

         @Column(name = "file_type_id", unique = false, nullable = false)
        public Long getFileType()
        {
            return fileType;
        }

        public void setFileType( Long fileType )
        {
            this.fileType = fileType;
        }

        @Column(name = "file_name", unique = false, nullable = false)
        public String getFileName()
        {
            return fileName;
        }

        public void setFileName( String fileName )
        {
            this.fileName = fileName;
        }

        @Column(name = "original_file_name", unique = false, nullable = false)
        public String getOriginaFileName()
        {
            return originaFileName;
        }

        public void setOriginaFileName( String originaFileName )
        {
            this.originaFileName = originaFileName;
        }

        @Column(name = "received_dt", unique = false, nullable = false)
        public Date getReceivedDt()
        {
            return receivedDt;
        }

        public void setReceivedDt( Date receivedDt )
        {
            this.receivedDt = receivedDt;
        }

         @Column(name = "record_count", unique = false, nullable = false)
        public Long getRecordCount()
        {
            return recordCount;
        }

        public void setRecordCount( Long recordCount )
        {
            this.recordCount = recordCount;
        }

        @Column(name = "client_id", unique = false, nullable = false)    
        public Long getClientId()
        {
            return clientId;
        }

        public void setClientId( Long clientId )
        {
            this.clientId = clientId;
        }

    }

DAO 接口(interface)

    import java.io.Serializable;
    import java.util.List;
    import java.util.Map;

    import org.hibernate.SessionFactory;
    import org.springframework.transaction.annotation.Transactional;

    public interface IGenericDAO< Entity extends Serializable, ID extends Serializable >
    {

        Entity getById( ID id );

        List<Entity> getAll();

        List<Entity> getAll( String contraints);

        List<Entity> search( Map<String, Object> parms );

        ID save( Entity entity );

        void saveOrUpdate( Entity entity );

        void update( Entity entity );

        void delete( Entity entity );

        void deleteById( ID id );

        void setSessionFactory( SessionFactory sessionFactory );

        void setEntity( final Class clazz );

    }

DAO 实现:

    @SuppressWarnings(value = "unchecked")
    public class GenericDAOImpl<Entity extends Serializable, ID extends Serializable>
            implements IGenericDAO<Entity, ID> {

        protected Class<Entity> clazz;

        public GenericDAOImpl(Class<Entity> clazz) {
            System.out.println(this.getClass().getSimpleName() + " called");
            this.clazz = clazz;
        }

        @Autowired
        @Qualifier("sessionFactory")
        protected SessionFactory sessionFactory;

        @Override
        public Entity getById(ID id) {
            System.out.println("GenericHibernateDAO.getById called with id: " + id);
            return (Entity) getCurrentSession().get(clazz, id);
        }

        @Override
        public List<Entity> getAll() {
            System.out.println("GenericHibernateDAO.getAll called");

            return getCurrentSession().createCriteria(clazz.getName()).list();


    //      return getCurrentSession().createQuery("from " + clazz.getName()).list();
        }

        @Override
        public List<Entity> getAll(String contraints) {
            System.out.println("GenericHibernateDAO.getAll called. Constraint : " + contraints);
            return getCurrentSession().createQuery("from " + clazz.getName() + " " + contraints ).list();
        }

        @Override
        public List search(Map<String, Object> parms) {
            Criteria criteria = getCurrentSession().createCriteria(clazz);

            for (String field : parms.keySet()) {
                criteria.add(Restrictions.ilike(field, parms.get(field)));
            }
            return criteria.list();
        }

        @Override
        public ID save(Entity entity) {
            Serializable id = null;
            try
            {
                id =  getCurrentSession().save(entity);
            }
            catch(RuntimeException e)
            {
                throw e;
            }
    //      getCurrentSession().flush();
    //      getCurrentSession().getTransaction().commit();

            return (ID)id;

        }

        @Override
        public void saveOrUpdate(Entity entity) {
            getCurrentSession().saveOrUpdate(entity);
            getCurrentSession().flush();
            getCurrentSession().getTransaction().commit();
        }

        @Override
        public void update(Entity entity) {
            getCurrentSession().update(entity);
            getCurrentSession().flush();
            getCurrentSession().getTransaction().commit();
        }

        @Override
        public void delete(Entity entity) {
            getCurrentSession().delete(entity);
            getCurrentSession().flush();
            getCurrentSession().getTransaction().commit();
        }

        @Override
        public void deleteById(ID id) {
            delete(getById(id));
        }

        protected Session getCurrentSession() {

            // return sessionFactory.openSession();
            return sessionFactory.getCurrentSession();
        }

        @Override
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }

        @Override
        public void setEntity(final Class clazz) {
            this.clazz = clazz;
        }

    }

最佳答案

您可以使用

noRollbackFor

事务注释的属性,例如@Transactional(noRollbackFor=SendMsgFailureException.class)。您需要处理缩进不回滚的父调用方方法的异常。

关于java - @事务: Is there a way that hibernate can persist child transacttion when parent fails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39479007/

相关文章:

java - 如何在同一容器中运行 COPY 和 RUN 命令?

java - Selenium:在组合框中选择一个项目

spring - 严重 : A child container failed during start java. util.concurrent.ExecutionException : org. apache.catalina.LifecycleException 在 Tomcat 中?

java - hibernate createSQLQuery批量插入

java - Maven 集成测试不适用于 Spring

Java - 打印分割字符串的几个不同部分

java - 对于实体,是否可以在 HQL 中使用与类名不同的名称

java - 为什么我在 JPA 中使用 Oracle 的悲观锁定不起作用

hibernate - 一对多关系的JPA更新列表

java - 插入批量更新没有错误,但受影响的行数为-2