我对JPA行为感到困惑,我没想到会这样做(使用Eclipselink)。
我在Wildfly 10(JDK-8)上运行无状态会话EJB(3.2)。我的方法调用是 - 默认情况下 - 封装在事务中。 现在,我的业务方法在读取和更新实体bean时,无法识别更新 - 尤其是实体的版本号。所以我的电话会产生一个
org.eclipse.persistence.exceptions.OptimisticLockException
我的代码看起来简化为:
public ItemCollection process(MyData workitem) {
....
// load document from jpa
persistedDocument = manager.find(Document.class, id);
logger.info("@version=" + persistedDocument.getVersion());
// prints e.g. 3
// change some data
....
manager.flush();
logger.info("@version=" + persistedDocument.getVersion());
// prints e.g. 4
....
// load document from jpa once again
persistedDocument = manager.find(Document.class, id);
logger.info("@version=" + persistedDocument.getVersion());
// prints e.g. 3 (!!)
// change some data
....
manager.flush();
// Throws OptimisticLockException !!
// ...Document@1fbf7c8e] cannot be updated because it has changed or been deleted since it was last read
...
}
如果我在用
注释的方法中放置代码(更改数据并刷新实体bean)@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
一切都按预期工作。
但为什么我的代码中的find()方法的第二次调用没有读取新的版本号?我希望在flush()和find()之后调用版本4。
答案 0 :(得分:2)
毕竟它看起来像是在呼叫
/*SOME useful css */
.nopadding{ padding:0 !important;} /*use important because I Overwrite the css in same file.*/
.nomargin{margin:0 !important;}/*use important because I Overwrite the css in same file.*/
/*This is your main CSS*/
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Ubuntu', sans-serif;
}
header {
background-color: #ff9900;
text-align: center;
color: black;
font-size: 30px;
height: 65px;
}
nav ul {
overflow: hidden;
list-style-type: none;
text-align: center;
}
nav ul li a {
display: block;
padding: 20px 10px;
font-size: 20px;
text-decoration: none;
background-color: #ff9900;
color: black;
}
nav ul li a:hover {
background-color: #e68a00;
}
nav ul li a:active {
background-color: #ffa31a;
color: white;
}
.row::after {
content: "";
clear: both;
display: block;
}
/* For mobile phones: */
[class*="col-"] {
float: left;
padding: 15px;
width: 100%;
}
@media only screen and (min-width: 600px) {
/* For tablets: */
.col-m-1 {width: 8.33%;}
.col-m-2 {width: 16.66%;}
.col-m-3 {width: 25%;}
.col-m-4 {width: 33.33%;}
.col-m-5 {width: 41.66%;}
.col-m-6 {width: 50%;}
.col-m-7 {width: 58.33%;}
.col-m-8 {width: 66.66%;}
.col-m-9 {width: 75%;}
.col-m-10 {width: 83.33%;}
.col-m-11 {width: 91.66%;}
.col-m-12 {width: 100%;}
}
@media only screen and (min-width: 768px) {
/* For desktop: */
.col-1 {width: 8.33%;}
.col-2 {width: 16.66%;}
.col-3 {width: 25%;}
.col-4 {width: 33.33%;}
.col-5 {width: 41.66%;}
.col-6 {width: 50%;}
.col-7 {width: 58.33%;}
.col-8 {width: 66.66%;}
.col-9 {width: 75%;}
.col-10 {width: 83.33%;}
.col-11 {width: 91.66%;}
.col-12 {width: 100%;}
}
解决了这个问题。我认为分离对象应该做同样的事情,但在我的情况下只调用clear()确实解决了问题。
毕竟调用方法detach()和flush()形成服务层似乎不是一个好主意。我这样做了,因为在我离开我的业务方法将这个id返回给客户端之前,我想得到我的实体的新版本ID。在这种情况下,我改变了我的策略,并删除了所有“坏事”。分离和刷新我的实体bean。代码变得更加清晰,毕竟代码复杂性大大降低。
当然,entityManager现在可以正常运行。如果我在一个事务中多次查询同一个实体bean,则entityManager返回正确的更新版本。
所以我自己的问题的答案是:只要没有充分的理由使用它们,就把方法刷新()和clear()。