远程EJB和JPA @Version

时间:2017-05-09 15:22:12

标签: java web-services jpa ejb

我正在开发的多层应用程序通过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;
    }

0 个答案:

没有答案