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); 现在它正常工作并且数据被正确修改:)非常感谢所有为此问题做出贡献的人! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |