我正在开发的多层应用程序通过Payara应用程序服务器访问其数据库。最初我使用webservices(jax-ws)来提供访问权限。通过在我的实体外观类上使用@WebService和@Stateless注释来轻松创建服务,促成了这一决定。
由于webservices的某些限制(例如在webservice接口中没有创建equals和hashCode方法),我决定尝试使用EJB来完成相同的功能。使用webservices,我能够在所有数据库实体上成功执行所有CRUD功能。我的所有实体类都扩展了一个AbstractEntity类,它注释了@MappedSuperClass。
@MappedSuperclass
public abstract class AbstractEntity {
@Column(name = "UUID")
@Basic
private String uuid;
@Version
@Access(AccessType.FIELD)
@Column(name = "Revision")
@Basic
private long revision;
public AbstractEntity() {
uuid = UUID.randomUUID().toString();
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
/**
* @return entity's database primary key if persisted
*/
public abstract Long getId();
public long getRevision() {
return revision;
}
public void setRevision(long revision) {
this.revision = revision;
}
/**
* @return true if this entity is persisted to database, false
otherwise.
*/
public boolean isPersisted() {
return getId() != null;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof AbstractEntity) {
return this.uuid.equals(((AbstractEntity) obj).uuid);
}
return false;
}
@Override
public int hashCode() {
return uuid.hashCode();
}
}
客户端应用程序正确地通过JNDI查找远程接口,并且我能够运行我的方法来查询数据并返回与使用webservices完全相同的结果列表。但是,问题在于每个实体实例返回的版本号和uuid。在所有情况下,返回的修订号都是0,而修订版和uuid与存储在数据库中的修订版和uuid不匹配。我已经验证我在服务器上查询的结果包含具有正确版本号的实体,但是当实体到达客户端时,所有这些实体都设置为0.当然,如果我对实体进行任何更改客户端然后尝试更新实体,我在更新方法上得到一个乐观的锁定异常。
这是否与从数据库中分离的实体有关?更新方法是:
@Override
public ShiplistItem updateShipList(ShiplistItem shipitem) {
LOGGER.log(Level.INFO, "Entering updateShipList.");
LOGGER.log(Level.INFO, "shipitem: {0}", shipitem.toString());
if (shipitem.isPersisted()) {
return em.merge(shipitem);
} else {
em.persist(shipitem);
return shipitem;
}
}
我不明白为什么webservice会正确返回实体,但是ejb似乎忽略了存储的修订版和uuid值。
所有帮助表示赞赏!!
编辑 - 实体类代码段
public class ShiplistItem extends AbstractEntity implements
Serializable, Comparable<ShiplistItem> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Long id;
....
编辑#2
@Override
public List<ShiplistItem> listShipListByDate(String date) {
Query query = em.createQuery("SELECT s from ShiplistItem s
where s.shipdate = :shipdate", ShiplistItem.class)
.setParameter("shipdate", date);
LOGGER.log(Level.INFO, "SQL: {0}.", query.toString());
List<ShiplistItem> result = new ArrayList<>();
try {
result = (List<ShiplistItem>) query.getResultList();
} catch (Exception ex) {
LOGGER.log(Level.INFO, "No shipping list for date {0}", date);
}
for (ShiplistItem shiplistItem : result) {
LOGGER.log(Level.INFO, "revision: {0}",shiplistItem.getRevision());
}
LOGGER.log(Level.INFO, "shiplist size: {0}", result.size());
return result;
}