EJB Problem mit Transaktionen

y0dA

Top Contributor
Vorweg wir benutzen JPA mit EJB 3.0 .

Folgende Sachlage:
Wir haben eine Controller-, eine Service- und eine DAOschicht und bisher brauchten wir immer nur 1 Statement - beispielsweise eine Person speichern wird vom "Personencontroller" angestossen, der ruft das Service auf welches wiederum dem DAO sagt "speichere mir das" = 1 Transaktion.
Nun ist es aber so dass bspw. eine Person ein Auto besitzt und selbiges wird nun verkauft und bekommt eine neue Person als Besitzer. Hierfür haben wir wieder einen Controller welcher dann aber , zur Zeit, 2 Services aufrufen muss. Zum einen muss er den alten Personensatz updaten (ein gueltigbis Timestamp setzen) und 2. muss ein anderes Service aufgerufen werden um der neuen Person das Auto umzuhängen.

Beides sollte aber in einer Transaktion laufen und so wie es jetzt ist sind es aber 2 Transaktionen. Sprich eigentlich sollten wir beide Dinge in einem Service abhandeln und hierbei ist das Problem dass wir nicht wissen wie wir hier 1 Transaktion durchführen können. Mit Spring hat das prima mit @Transactional funktioniert, dies bietet EJB aber nicht an.

Hat jemand einen Lösungsvorschlag?

hier die abstrakte dao klasse, selbige wird dann bspw. von Person (PersonDAO) und Auto(AutoDAO) implementiert.

Java:
public abstract class CRUDEntityFacade<T extends XObjekt> implements
		IGenericEntityFacade<T> {
	private static Logger logger;

	protected transient final Class<T> entityClass;

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

	@SuppressWarnings("unchecked")
	public CRUDEntityFacade() {
		entityClass = (Class) ((java.lang.reflect.ParameterizedType) this
				.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
		logger = Logger.getLogger(this.getClass());
	}

	@Override
	public T create(T entity) throws EntityExistsException,
			IllegalStateException, IllegalArgumentException,
			TransactionRequiredException {
		if (logger.isTraceEnabled()) {
			logger.trace("CRUDEntityFacade.create("
					+ entityClass.getSimpleName() + ")");
		}
		em.persist(entity);

		return entity;
	}

	@Override
	public T update(T entity) throws IllegalStateException,
			IllegalArgumentException, TransactionRequiredException {
		if (logger.isTraceEnabled()) {
			logger.trace("CRUDEntityFacade.update("
					+ entityClass.getSimpleName() + ")");
		}
		em.merge(entity);

		if (logger.isDebugEnabled()) {
			logger
					.debug("CRUDEntityFacade.update(Serializable) updated 1 entity: "
							+ entity.toString());
		}
		return entity;
	}
 

mvitz

Top Contributor
Sind genau hierfür nicht die Annotation

javax.ejb.TransactionManagement
und
javax.ejb.TransactionAttribute

da?

Wenn man den DAOs ein TransactionAttribute REQUIRED hinzufügt, und dann beide DAOs aus dem Service heraus aufruft, sollten die afaik in einer Transaktion stattfinden.
 

y0dA

Top Contributor
Sind genau hierfür nicht die Annotation

javax.ejb.TransactionManagement
und
javax.ejb.TransactionAttribute

da?

Wenn man den DAOs ein TransactionAttribute REQUIRED hinzufügt, und dann beide DAOs aus dem Service heraus aufruft, sollten die afaik in einer Transaktion stattfinden.

Fragst du mich jetzt oder meinst du dass das so ist?
 

mvitz

Top Contributor
So halb/halb ;)

Ich habe noch nicht so viel Erfahrung mit EJBs, bin aber der Meinung, dass man die DAOs und Services mit javax.ejb.TransactionAttribute annotieren und den passenden Wert einstellen sollte.
Die Annotation kann man an die Klasse machen und dann zusätzlich noch an abweichende Methoden.

Die Frage in dem Post ging eher in die Richtung, dass das jemand anderes der das hier ließt nochmal bestätigt, nicht das ich Mist verzapfe.

Aber evtl. hilft dir ja schon mal nach javax.ejb.TransactionAttribute zu googlen.
 

y0dA

Top Contributor
Also wie du schon gesagt hast, es funktioniert mit

Java:
@TransactionManagement

hierbei kann man sich dann entscheiden ob das Transaktionsmanagement der Container übernehmen soll oder die Bean. Ich habe mich für die Bean entschieden und das sieht dann so aus:

Java:
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class ServiceA implements ServiceALocal {
	@Resource
	UserTransaction tx;

public void doXXX(ObjektA a,
			ObjektB b) {
		try {
			tx.begin();
			aFacade.update(a);
			bFacade.update(b);
			tx.commit();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
Mit dieser Variante "erspart man sich
Java:
@TransactionAttribute
selbiges ist nur für den Container notwendig, also wenn der Container das Transaktionsmanagement übernimmt.
 

mvitz

Top Contributor
Hatte ich ja mit meinem Halbwissen tatsächlich einen Treffer. :D Darf ich noch fragen, wieso du Bean Managed Transaktionen nutzt und nicht einfach die (zumindest vermeintlich) bequemeren Container Managed Transaktionen?
 

y0dA

Top Contributor
Hatte ich ja mit meinem Halbwissen tatsächlich einen Treffer. :D Darf ich noch fragen, wieso du Bean Managed Transaktionen nutzt und nicht einfach die (zumindest vermeintlich) bequemeren Container Managed Transaktionen?

Ja weil ich mit dem Containerzeug die @TransactionAttribute Annotation in die DAO Klassen setzen müsste und ich vllt. eine dieser DAOs auch noch woanders aufrufen möchte ohne dass selbige dann sich in eine laufende Transaktion hängt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Problem mit EJBs und Transaktionen Data Tier 0
N Problem beim initialisieren des Caches Data Tier 0
S JPA Problem mit Cascading Data Tier 1
M Eclipse 4 RCP Hibernate Problem Data Tier 3
C JPA FetchType.LAZY, Relation @OneToMany und Problem mit dem update Data Tier 1
G JPA: Entity Klasse @JoinColumns Problem Data Tier 2
M JPA Problem: java.sql.SQLSyntaxErrorException: Data Tier 7
H Hibernate Problem mit Lazy Loading bei @OneToMany Collections Data Tier 5
M MySql und JPA-Timestamp Problem Data Tier 8
J Hibernate Problem bei Master-Detail-Tabellen Data Tier 5
A JPA - ManyToMany Problem - keine Unique Mehrfachzuweisungen Data Tier 4
M Problem beim Laden von Objekten, die von anderen Applikationen in eine DB eingefügt wurden Data Tier 5
M Problem mit @Temporal Mapping und SQL Server Data Tier 3
P JPA - HashMap mit Many-to-Many Relation Problem Data Tier 4
B Problem mit @ManyToMany und CascadeType.ALL Data Tier 3
Blackskyliner [JPA][Anfänger] Problem mit Wertzuweisung aus Verbundtabelle Data Tier 2
B Problem mit org.hibernate.LazyInitializationException Data Tier 11
B DatenquellenUpdater extends Thread - Problem mit PermGenSpace Data Tier 5
S Problem beim Insert mit Hibernate Data Tier 9
Y [openJPA] Problem mit Transaktion? Data Tier 2
A @SecondaryTable Problem Data Tier 9
N Problem beim session.flush(); Data Tier 17
Y Postgres und JPA - Primärschlüssel Problem Data Tier 3
P SQL PRoblem Hibernate? Data Tier 8
M Transaction / Session Problem Data Tier 4
G JPA 2.0 Query Problem Data Tier 3
P CORBA Problem bei EJB 3.0 Anwendung in Glassfish v3 Data Tier 7
F Problem mit Hibernate Schema Update Data Tier 2
S Lazy loading Problem Data Tier 2
M Insert-Problem mit JPA/Hibernate Data Tier 4
megachucky JPA - Problem mit Persistence Unit / Context Data Tier 1
H Hibernate Problem Data Tier 4
D Performance Problem mit Prepared Statement Data Tier 6
T Problem mit openJPA Data Tier 7
P Problem mit Data Tier 9
GilbertGrape Cascade Problem (Hibernate) Data Tier 3
C JPA Problem mit attributeOverride und mehrspaltigem PK Data Tier 2
B select "neu" statement Problem (jpql) Data Tier 8
boxi Hibernate Lazy Loading Problem Data Tier 2
M Problem mit Hibernate und SLF4J - NoSuchMethodException Data Tier 3
G Connection Problem - WAS 6.1, Hibernate, OS Authentication Data Tier 1
K Hibernate update-Problem Data Tier 36
J hibernate problem Data Tier 14
N Hibernate - Problem mit Update/Insert Data Tier 4
B Problem mit @PersistenceContext Data Tier 4
G Problem with mapped of the tables at one to one relationship Data Tier 8
C JPA JPA Transaktionen für Web-Application und Desktop-Client Data Tier 1
V Grundsätzliche Frage zu JPA, mehreren Enitäten und Transaktionen Data Tier 14
M JPA-Transaktionen Webapplication Data Tier 2

Ähnliche Java Themen


Oben