加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 带JPA JTA的@Stateless webservice:如何提交被管实体的

发布时间:2020-12-14 19:35:27 所属栏目:Java 来源:网络整理
导读:我有以下简单的webservice声明为@Freeless EJB在GlassFish 3.1.2.2上运行,EclipseLink 2.4.1使用JTA DataSource连接到 MySQL数据库: @POST@Consumes(MediaType.APPLICATION_JSON)public Response update(TimeRow e) throws Exception { if ((e.getKey() ==
我有以下简单的webservice声明为@Freeless EJB在GlassFish 3.1.2.2上运行,EclipseLink 2.4.1使用JTA DataSource连接到 MySQL数据库:
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response update(TimeRow e) throws Exception {
    if ((e.getKey() == null) || !e.getKey().keyValid()) {
        return Response.status(400).build();
    }

    TimeRow existing = em.find(TimeRow.class,e.getKey());
    if (existing == null) {
        em.persist(e);
    } else {
        existing.setValues(e.getValues());
        em.flush();
    }
    return Response.status(204).build();
}

TimeRow的实体类:

@Entity
@NamedQueries({
    @NamedQuery(name="TimeRow.findAllByUser",query="SELECT t FROM TimeRow t WHERE t.table.userId = :uid")
})
public class TimeRow implements Serializable {

    @EmbeddedId
    private TimeRowPK key;

    @MapsId("userId")
    @JoinColumn(name = "USERID",referencedColumnName = "userId")
    @ManyToOne
    private UserTable table;
    @Column(name="ROWVALUES")
    private List<Double> values;

    public TimeRow() {
        this.key = new TimeRowPK();
        this.values = new ArrayList<Double>(20);
        extendValuesTo20();
    }

    public TimeRow(String uid,Date date) {
        this.key = new TimeRowPK(date,uid);
        this.table = new UserTable(uid);
        this.values = new ArrayList<Double>(20);
        extendValuesTo20();
    }

    public List<Double> getValues() {
        return values;
    }

    public void setValues(List<Double> values) {
        this.values = values;
        extendValuesTo20();
    }

    private void extendValuesTo20() {
        if (this.values.size() < 20) {
             for (int i = this.values.size(); i < 20; i++) {
                  this.values.add(0.0);
             }
        }
    }

}

@EmbeddableId TimeRowPK:

@Embeddable
public class TimeRowPK implements Serializable {

    public TimeRowPK() { }

    public TimeRowPK(Date date,String userId) {
        this.date = date;
        this.userId = userId;
    }

    @Column(name="DAY")
    private Date date;
    @Column(name = "USERID")
    private String userId;

    public boolean keyValid() {
        return ((date != null) && ((userId != null) && !userId.isEmpty()));
    }

}

persistence.xml(没有< persistence>标记):

<persistence-unit name="test" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/test</jta-data-source>
    <class>com.test.TimeRow</class>
    <class>com.test.TimeRowPK</class>
    <class>...</class>
    <properties>
        <property name="eclipselink.ddl-generation" value="create-tables" />
        <property name="eclipselink.ddl-generation.output-mode" value="database" />
    </properties>
</persistence-unit>

Web服务声明:

@Path("row")
@Stateless
public class TimeRowWebService {

    @PersistenceContext(unitName = "test")
    private EntityManager em;

    ...

}

问题是如果实体存在,则更改仅存储在PersistenceContext中,但它们不会提交到数据库.这意味着我可以使用更改检索正确的数据,但是例如,如果我重新启动AS,则更改将消失. AS日志中没有错误.

所以我想我必须做一些bean级别的手动事务处理来完成这项工作.我究竟需要添加什么才能使其正常工作?

解决方法

在努力使@EmbeddedId方式运行之后,我尝试使用生成的@Id实现它,然后为这两个关键字段添加一个唯一约束.

实体

public class TimeRow implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @JoinColumn(name = "USERID",referencedColumnName = "USERID")
    @ManyToOne(optional = false)
    private UserTable table;

    @Basic(optional = false)
    @Column(name = "DAY")
    @Temporal(TemporalType.DATE)
    private Date date;

    @Lob
    @Column(name="ROWVALUES")
    private List<Double> values;

    ...
}

另外,我已经将数据库引擎从MyISAM更改为InnoDB以获得更好的外键支持.为此,我在[mysqld]部分下添加了default-storage-engine = innodb到/etc/mysql/my.cnf.

使用DDL生成数据库结构后,对于USERID和DAY,我有added a unique constraint:

alter table TIMEROW add unique index(USERID,DAY);

现在它正常工作并且数据被正确修改:)非常感谢所有为此问题做出贡献的人!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读