英文:
java jpa hibernate rollback on onetomany
问题
以下是翻译好的内容:
我有一个用于我的 JPA 模型表单头部的模型:
@Entity
@Table(name = "Form_Header")
public class FormHeader {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "header_id", nullable = false)
    private Long headerId;
    @OneToMany(
        mappedBy = "formHeader",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List<FormProdItem> formProdItem;
    // 更多字段
    // getter 和 setter
}
还有另一个我认为是子级的模型,更多关于单向的:
@Entity
@Table(name = "Form_Prod_Item")
public class FormProdItem {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "item_id", nullable = false)
    private Long itemId;
    @Column(name = "header_id", nullable = false)
    private Long headerId;
    @ManyToOne(fetch = FetchType.LAZY)
    private FormHeader formHeader;
    // 更多字段
    // getter 和 setter
}
以及用于访问数据库的 DAO:
@Repository
@Transactional
public class FormHeaderDAO {
 
    @Autowired
    private EntityManager entityManager;
    
    public List<FormHeader> gettest() {
    	
        try {
        	
            String sql = "SELECT e FROM FromHeader e "
                         + "WHERE e.isDeleted = 0 ";
        	
            Query query = entityManager.createQuery(sql, FormHeader.class);
        	
            return (List<FormHeader>) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        } catch (Exception e) {
            return null;
        }
    }
}
我得到了这个错误,没有进一步的细节:
2020-09-16 09:19:10.324 ERROR 9624 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only] with root cause
org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
即使我在 SQL 查询中添加了 "join e.formProdIem f",错误仍然相同,并且不会提供更多的细节。有任何想法为什么会出现这种情况吗?
英文:
I have a model formheader for my jpa which i consider the parent
@Entity
@Table(name = "Form_Header")
public class FormHeader {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "header_id", nullable = false)
    private Long headerId;
    @OneToMany(
        mappedBy = "formHeader",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List<FormProdItem> formProdItem;
    -- more fields--
    -- getter and setter--
}
and another model which I consider as the child. more on unidirectional
@Entity
@Table(name = "Form_Prod_Item")
public class FormProdItem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "item_id", nullable = false)
    private Long itemId;
    @Column(name = "header_id", nullable = false)
    private Long headerId;
    @ManyToOne(fetch = FetchType.LAZY)
    private FormHeader formHeader;
   -- more fields --
   -- getter and setter --
}
and my DAO to access the DB
@Repository
@Transactional
public class FormHeaderDAO {
    @Autowired
    private EntityManager entityManager;
    public List<FormHeader> gettest() {
	
        try {
    	
    	    String sql = " SELECT e FROM FromHeader e "
    	    + " WHERE  e.isDeleted = 0 ";
    	
    	    Query query = entityManager.createQuery(sql, FormHeader.class);
    	
        
            return (List<FormHeader>) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        } catch (Exception e) {
            return null;
        }
    }
}
I'm getting this error without any further details
2020-09-16 09:19:10.324 ERROR 9624 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only] with root cause
org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
even if I add in sql "join e.formProdIem f" the error is the same and it wont provide and more details. Any idea why?
答案1
得分: 1
我的猜测是,你遇到了**NonUniqueResultException**,因为你的查询返回了多个结果,然后你调用了**query.getSingleResult()**,但你可能没有注意到这一点,因为你在捕捉异常并且没有显示地处理它们。这是一个非常糟糕的做法。
    @Slf4j
    @Repository
    @Transactional
    public class FormHeaderDAO {
    
        @Autowired
        private EntityManager entityManager;
    
        public List<FormHeader> gettest() {
        
            try {
                String sql = "SELECT e FROM FromHeader e "
                + "WHERE e.isDeleted = 0 ";
            
                Query query = entityManager.createQuery(sql, FormHeader.class);
            
                return (List<FormHeader>) query.getSingleResult();
            } catch (NoResultException e) {
                log.error(e);
                return null;
            } catch (NonUniqueResultException e) {
                log.error(e);
                return null;
            } catch (Exception e) {
                log.error(e);
                return null;
            }
        }
    }
如果你没有使用 Slf4j,可以使用 System.err.println() 或者设置断点来确认你的代码目前正在忽略哪种类型的异常。
英文:
My guess is you are getting a NonUniqueResultException because your query returns more than one result and you call query.getSingleResult() but you don't see that because you are catching exceptions and discarding them silently. Which is a really bad idea.
@Slf4j
@Repository
@Transactional
public class FormHeaderDAO {
    @Autowired
    private EntityManager entityManager;
    public List<FormHeader> gettest() {
    
        try {
            String sql = " SELECT e FROM FromHeader e "
            + " WHERE  e.isDeleted = 0 ";
        
            Query query = entityManager.createQuery(sql, FormHeader.class);
        
            return (List<FormHeader>) query.getSingleResult();
        } catch (NoResultException e) {
            log.error(e)
            return null;
        } catch (NonUniqueResultException e) {
            log.error(e)
            return null;
        } catch (Exception e) {
            log.error(e)
            return null;
        }
    }
}
If you don't have Slf4j use System.err.println() or a break point to confirm what kind of exception your code is swallowing right now.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论