JSP Hibernate抛出异常,但仅在首次执行时抛出

bsxbgnwa  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(127)

我有一个名为"退款"的实体,它在名为"动机"的同一个实体上有两个外键。
Refund.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

Motivation.java

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

// getters and setters

这个类没有注解,因为它有一个扩展,并且它是由Hibernate自动绑定的,在hbm.xml中。@ManyToOne工作完美,表存在,并且在数据库(Oracle)中有一些元素。
在JSP中,我需要用这个表的元素填充一个组合框,并通过type列进行过滤。
正如我在这里所做的:
MotivationDAO.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。我试着浏览互联网,找到了this article。应用修复程序后,它仍然给我一个错误,但一个不同的异常:ids for this class must be manually assigned before calling save()。再次尝试浏览并找到this post,但它建议为类添加一个自动递增的列ID。这不是我所需要的,而且,我不能添加它。
奇怪的是,如果我刷新JSP上相同的"bug"退款,它的工作完美。我尝试了一些修复,实际上也解决了这个问题,但然后我得到一些回退保存,如:
1.将一些属性添加到外键注解中,例如:updatable=false ..但是它对我不起作用,因为字段必须是可更新的。放置updatable=true不能解决问题。
1.从组合框路径中的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
1.捕获异常并在捕获时重新启动同一函数
1.将列表添加到currentPL中,这样可以正确检索列表,但是在保存或刷新之后,它会再次抛出相同的异常。
1.默认情况下在null上设置动机,因为可能由于null代码没有动机,因此Hibernate无法找到外键,但什么也找不到。
1.添加自动生成的ID列
1.将两个外键分隔为两个单独的实体
1.关闭休眠会话
我不清楚的是:为什么我改变一个完全分离的代码片段就能解决问题?2为什么它在第二轮就能工作?
提前感谢愿意帮忙的人!

r8uurelv

r8uurelv1#

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

相关问题