【发布时间】: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,它会完美运行。我尝试了一些实际上也解决了问题的修复程序,但后来我在保存时遇到了一些回归问题,例如:
-
在外键注解中添加一些属性,例如:
updatable=false.. 但它对我不起作用,因为字段必须可更新。输入updatable=true并不能解决问题。 -
从组合框路径中的
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>将完整的实体发送到后端,但它没有(实体似乎为空)。
- 重构组合框语法,使用
bean:define代替c:forEach - 捕获异常并在捕获时重新启动相同的功能
- 将列表添加到
currentPL中,这样可以正确检索列表,但在保存或刷新后,它会重新抛出相同的异常。 - 默认在
null上设置动机,因为可能因为没有null代码的动机,所以 Hibernate 找不到外键,但什么也找不到。 - 添加自动生成的 ID 列
- 在两个分离的实体中分离两个外键
- 关闭休眠会话
我不清楚的是:如果我更改一个完全分离的 sn-p 代码,为什么它可以解决问题?为什么它在第二轮有效?
- 重构组合框语法,使用
【问题讨论】:
标签: java hibernate jsp jpa struts-1