java jpa hibernate中的onetomany回滚功能

huangapple go评论65阅读模式
英文:

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 = &quot;Form_Header&quot;)
public class FormHeader {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = &quot;header_id&quot;, nullable = false)
    private Long headerId;

    @OneToMany(
        mappedBy = &quot;formHeader&quot;,
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List&lt;FormProdItem&gt; formProdItem;

    -- more fields--

    -- getter and setter--

}

and another model which I consider as the child. more on unidirectional

@Entity
@Table(name = &quot;Form_Prod_Item&quot;)
public class FormProdItem {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = &quot;item_id&quot;, nullable = false)
    private Long itemId;

    @Column(name = &quot;header_id&quot;, 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&lt;FormHeader&gt; gettest() {
	
        try {
    	
    	    String sql = &quot; SELECT e FROM FromHeader e &quot;
    	    + &quot; WHERE  e.isDeleted = 0 &quot;;
    	
    	    Query query = entityManager.createQuery(sql, FormHeader.class);
    	
        
            return (List&lt;FormHeader&gt;) 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&lt;FormHeader&gt; gettest() {
    
        try {
            String sql = &quot; SELECT e FROM FromHeader e &quot;
            + &quot; WHERE  e.isDeleted = 0 &quot;;
        
            Query query = entityManager.createQuery(sql, FormHeader.class);
        
            return (List&lt;FormHeader&gt;) 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.

huangapple
  • 本文由 发表于 2020年9月16日 09:25:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/63911877.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定