【问题标题】:Hibernate throws exception, but only on first executionHibernate 抛出异常,但仅在第一次执行时
【发布时间】:2023-01-12 21:17:37
【问题描述】:

我有一个名为 Refund 的实体,它在同一个名为 Motivation 的实体上有两个外键。

退款.java

// other columns

@ManyToOne(targetEntity=Motivation.class, optional=true, fetch=FetchType.LAZY)
@JoinColumn(name="opening_motivation", referencedColumnName="code")
@ForeignKey(name="REFUND_OPENING_MOTIVATION_FK")
private Motivation openingMotivation;

@ManyToOne(targetEntity=Motivation.class, optional=true, fetch=FetchType.LAZY)
@JoinColumn(name="closure_motivation", referencedColumnName="code")
@ForeignKey(name="REFUND_CLOSURE_MOTIVATION_FK")
private Motivation closureMotivation;

// getters and setters

动机.java

private String code;
private String type;
private String description;

// getters and setters

这个类没有注释,因为它有一个扩展,并且它被 Hibernate 自动绑定,在 hbm.xml. @ManyToOne 工作完美,表存在并且在数据库(Oracle)中有一些元素。

在 JSP 中,我需要用这个表的元素填充一个组合框,由 type 列过滤。

正如我在这里所做的那样:

动机DAO.java

public static List<Motivation> getMotivationsByType(String type) throws DatabaseException  {
    
    Criteria criteria = null;
    
    try {
        Session session = HibernateUtil.currentSession();
        
        criteria = session.createCriteria(Motivation.class);
        criteria.add(Restrictions.eq("type", type);
        return (List<Motivation>) criteria.list(); // the exception I specified later is thrown here
    
    } catch (HibernateException e) {
        throw new DatabaseException(e.getMessage());
    }catch (Exception e) {
        System.out.println("getMotivationList: " + e.getMessage());
        throw new DatabaseException("an error occured");
    }
}

并且,在 JSP 中:

<form:select cssClass="comboBox" path="pageAction.currentPL.entity.openingMotivation.code" id="openingCombo" disabled="true">
    <form:option value=""></form:option>
    <c:forEach var="openingMotivation" items='<%=MotivationDAO.getMotivationsByType("A")%>'>            
        <form:option value="${openingMotivation.code}">${openingMotivation.code} - ${openingMotivation.description}</form:option>
    </c:forEach>
</form:select>

问题是:对于一些退款(与“工作”退款完全没有区别),getMotivationsByType() 函数给出了一个例外:object references an unsaved transient instance - save the transient instance before flushing。我尝试浏览 Internet 并找到了this article。应用修复后,它仍然给我一个错误,但是一个不同的异常:ids for this class must be manually assigned before calling save()。再次尝试浏览并找到this post,但它建议为该类添加一个自增列Id。这不是我需要的,另外,我无法添加它。

奇怪的是,如果我在同一个“有问题的”Refund 上刷新 JSP,它会完美运行。我尝试了一些实际上也解决了问题的修复程序,但后来我在保存时遇到了一些回归问题,例如:

  1. 在外键注解中添加一些属性,例如:updatable=false.. 但它对我不起作用,因为字段必须可更新。输入updatable=true 并不能解决问题。

  2. 从组合框路径中的 property 中删除 code,如下所示:

    <form:select cssClass="comboBox" path="pageAction.currentPL.entity.openingMotivation" id="openingCombo" disabled="true">
        <form:option value=""></form:option>
        <c:forEach var="openingMotivation" items='<%=MotivationDAO.getMotivationsByType("A")%>'>            
            <form:option value="${openingMotivation}">${openingMotivation.code} - ${openingMotivation.description}</form:option>
        </c:forEach>
    </form:select>
    

    将完整的实体发送到后端,但它没有(实体似乎为空)。

    1. 重构组合框语法,使用bean:define代替c:forEach
    2. 捕获异常并在捕获时重新启动相同的功能
    3. 将列表添加到currentPL 中,这样可以正确检索列表,但在保存或刷新后,它会重新抛出相同的异常。
    4. 默认在null 上设置动机,因为可能因为没有null 代码的动机,所以 Hibernate 找不到外键,但什么也找不到。
    5. 添加自动生成的 ID 列
    6. 在两个分离的实体中分离两个外键
    7. 关闭休眠会话

    我不清楚的是:如果我更改一个完全分离的 sn-p 代码,为什么它可以解决问题?为什么它在第二轮有效?

【问题讨论】:

    标签: java hibernate jsp jpa struts-1


    【解决方案1】:

    这不是一个合适的解决方案,但我发现问题是由会话和线程引起的。在这个项目中,它使用了一个内部方法来使用线程检索 Hibernate 当前会话。通过更改线程号,将在使用当前会话的下一个实例中抛出异常。因此,如果您遇到同样的问题,请尝试调查这些事情。

    【讨论】:

      猜你喜欢
      • 2017-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多