我尝试使用Ebean
程序中的Play! Framework
更新数据库中的一行。
这是我想要更新的实体的类。
的 Transaction.java
@Entity
@Table(name = "transactions")
public class Transaction extends Model{
@Id
@GeneratedValue
public int id;
@OneToOne
@JoinColumn(name = "car_fk")
public Car car;
@OneToOne
@JoinColumn(name = "user_lender_fk")
public User user;
@Version
public Timestamp from_date;
@Version
public Timestamp to_date;
public boolean availability; // true -> Available.
public String status;
}
以下是我用来更新它的方法:
Transaction transaction = new Transaction();
transaction.car = concernedCars.get(i);
transaction.user = currentUser;
transaction.from_date = Tools.StringAndroidToTimestamp(dateFrom);
transaction.to_date = Tools.StringAndroidToTimestamp(dateTo);
transaction.status = Constants.WAITING_FOR_ANSWER;
try{
Ebean.update(transaction);
}catch(OptimisticLockException e){
Logger.info(e.toString());
}
如有必要,我的方法是将 String
转换为Timestamp
:
public static Timestamp StringAndroidToTimestamp(String s){
String toConvert = s.substring(0, s.length()-2);
Logger.info("ToConvert = "+toConvert);
Timestamp timestamp = null;
try{
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date parsedDate = dateFormat.parse(toConvert);
timestamp = new Timestamp(parsedDate.getTime());
}catch(Exception e){
Logger.info("Exception date = " +e.toString());
}
return timestamp;
}
当然,我收到了一个神话般的错误:
javax.persistence.OptimisticLockException:数据已更改。更新 [0]行sql
我做错了什么?
答案 0 :(得分:4)
有几种方法可以解决这个问题。
1)在类名之前使用@EntityConcurrencyMode(ConcurrencyMode.NONE)
2)使用原始更新查询。(首选)
我面临太多问题,因为同样的ebean.update抛出乐观锁异常,最后我做了原始更新查询,它对我有用。
答案 1 :(得分:0)
我可以从这里看到一些问题:
update
但似乎您确实在创建新的交易,因此您应该使用Ebean.save
关于错误,当您尝试更新在加载它和更新之间发生更改的记录时,会引发该异常。为了找出记录已更改,Ebean使用Version列中的值。
因此,代码中的更新将生成类似于此的SQL:
UPDATE transactions
SET car_fk=<SOME_VAL>, ...
WHERE id=null AND from_date=<OTHER_VAL> AND to_date=<ANOTHER_VAL>
不会更新任何记录并抛出该异常。
我发布此信息是因为我不知道在Play&lt; 2.4.x附带的Ebean版本中禁用乐观锁定的简单方法,您可能会再次发现该错误。通常,您可以使用版本字段并使用事务或重新加载/重试操作来最小化它。
答案 2 :(得分:0)
我有一个解决这个问题的替代方案 你可以使用:
@EntityConcurrencyMode(ConcurrencyMode.NONE)
在您的实体类
中这将禁用乐观锁定并发修改检查 新的SQL查询将是:
更新TABLE-NAME SET PARAM1 =? WHERE ID =?
EntityConcurrencyMode来自包
package com.avaje.ebean.annotation;