Tôi đã webservice đơn giản sau đây khai báo là @Stateless
EJB chạy trên GlassFish 3.1.2.2 với EclipseLink 2.4.1 bằng cách sử dụng JTA DataSource
để kết nối với một cơ sở dữ liệu MySQL:@Dịch vụ web không gian với JPA + JTA: Cách thực hiện thay đổi đối tượng được quản lý?
@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();
}
Entity lớp 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
(không có thẻ <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>
khai Webservice:
@Path("row")
@Stateless
public class TimeRowWebService {
@PersistenceContext(unitName = "test")
private EntityManager em;
...
}
Vấn đề là nếu thực thể tồn tại, những thay đổi được chỉ được lưu trữ trong PersistenceContext
, nhưng họ không cam kết kho dữ liệu. Có nghĩa là tôi có thể truy xuất dữ liệu chính xác với các thay đổi, nhưng ví dụ nếu tôi khởi động lại AS, các thay đổi sẽ biến mất. Không có lỗi trong nhật ký AS.
Vì vậy, tôi đoán tôi phải thực hiện xử lý giao dịch thủ công ở cấp độ đậu để có được công việc này. Chính xác thì tôi phải thêm gì để làm việc này?
Đậu có được khai báo @Stateless không? –
Vâng, đúng vậy! –
Trong trường hợp này, tôi không thể thấy lỗi ở đây ... '@ Stateless' ngụ ý' @TransactionAttribute (REQUIRED) 'nếu bạn không thay đổi ... Có thể nó nằm trong' MyEntity.setValues () 'hoặc trong bản khai báo 'MyEntity'.Bạn có thể đăng mã 'MyEntity' không? –