Ich habe die folgende einfache Webservice deklariert als @Stateless
EJB auf Glassfish 3.1.2.2 mit Eclipselink läuft 2.4.1 mit einem JTA DataSource
zu einer MySQL-Datenbank verbinden:@Stateless Webservice mit JPA + JTA: Wie Änderungen der verwalteten Einheit festgeschrieben werden?
@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 Klasse von 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
(ohne <persistence>
Tag):
<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>
Webservice Erklärung:
@Path("row")
@Stateless
public class TimeRowWebService {
@PersistenceContext(unitName = "test")
private EntityManager em;
...
}
Das Problem ist, dass, wenn die Einheit existiert, gehen die Änderungen gespeichert nur im PersistenceContext
, aber sie sind nicht verpflichtet, die Datenbank. Das bedeutet, dass ich die richtigen Daten mit den Änderungen abrufen kann, aber wenn ich zum Beispiel das AS neu starte, sind die Änderungen weg. Im AS-Protokoll sind keine Fehler aufgetreten.
Also ich denke, ich muss einige manuelle Transaktion Handhabung auf Bohnenebene tun, um diese Arbeit zu bekommen. Was genau muss ich hinzufügen, damit das funktioniert?
Ist die Bean @Stateless deklariert? –
Ja, das stimmt! –
In diesem Fall kann ich hier keinen Fehler sehen ... "@ Stateless" impliziert '@TransactionAttribute (REQUIRED)', wenn Sie es nicht ändern ... Vielleicht liegt es in 'MyEntity.setValues ()' oder in der 'MyEntity'-Deklaration selbst.Können Sie den 'MyEntity' Code posten? –