# CDI und EJB im Zusammenspiel mit EntityManager



## Gast2 (16. Mai 2011)

Hallo zusammen,

da nicht genau weiß wo das Problem ist oder ob das Verhalten normal ist. Hole ich mal etwas weiter aus und mache auch konkrete Beispiele.

Ich hab folgende Klassen:
Entitity

```
@Entity
public class HibAngebot implements Serializable {
    @Id
    private Long id;

    public Long getId() {
        return this.id;
    } 
    public void setId(Long pk) {
        this.id = pk;
    }
```

Dao

```
@Stateful
public class MyDAOImpl implements MyDAO{

	@PersistenceContext(unitName = "MyUnit", type=PersistenceContextType.EXTENDED)
	private EntityManager entityManager;

	@Override
	public Angebot findAngebotById(long angebotsId) {
		return entityManager.find(Angebot.class, angebotsId);
	}
	
}
```
Ich habe um das Problem mal zu erklären 2 gleiche Services gemacht:

Service 2

```
public class AngebotService2Impl implements AngebotService2 {

	@Inject
	private MyDAO myDAO;

	@Override
	public Set<Angebot> getAngebote() {
		Set<Angebot> angebote = new HashSet<Angebot>();
		angebote.add(myDAO.findAngebotById(265593));
		return angebote;
	}
}
```

Service 1

```
public class AngebotRemoteServiceImpl implements AngebotRemoteService {

	@Inject
	private MyDAO myDAO;
	
	@Inject
	private AngebotService2 angebotService2;

	@Override
	public Set<HibAngebot> getAngebote() {
		Set<Angebot> angebote = new HashSet<Angebot>();

		HibAngebot angebot = myDAO.findAngebotById(265593);
angebote.add(findAngebotById(265593));
		HibAngebot angebot2 = myDAO.findHibAngebotById(265593);
		
		System.out.println(angebot2.equals(angebot)); -->true
		Set<Angebot> angebote2 = angebotService2.getAngebote();
		System.out.println(angebote2.contains(angebot));--> false =(

		return angebote ;
	}
}
```


Ich injekte einen Service in einen anderen also. Der EntityManager ist immer die gleiche Instanz. Aber ich habe 2 verschiedene DAO Instanzen, deshalb werden im 2ten Service andere Instanzen von dem Angebot geladen als im 1 (siehe 2ter if). 

Ich würde gern für den einen Aufruf immer das gleiche DAO verwenden, damit die Instanzen auch die gleiche aus dem EntityManager sind. Wie macht man sowas besser, damit für alle calls und subcalls die gleichen Instanzen geladen werden, damit sowas wie im 1. if funktioniert? 
Einen Wrapper um den DAO bauen? Oder gibt es irgendwo eine Annotation in CDI oder EJB die gewährleistet, dass man so ein shared DAO hat?


----------



## AFlieger (18. Mai 2011)

Hallo,

mir fällt jezt ganz banal ein, das MyDAOImpl mit *@Singleton* zu annotieren, dann dürftest du dauerhaft nur eine Instanz haben.


----------



## Gast2 (19. Mai 2011)

AFlieger hat gesagt.:


> Hallo,
> 
> mir fällt jezt ganz banal ein, das MyDAOImpl mit *@Singleton* zu annotieren, dann dürftest du dauerhaft nur eine Instanz haben.



Nee dann ist es für jeden Client so, dass wäre nicht Sinn der Sache 

Stateful Beans haben den gleichen EntityManager steht in der Spec, das passt eigentlich auch, Aber ich versteh nicht warum der gleiche EntityManager unterschiedliche Instanzen zurückgibt.:bahnhof:


----------



## FArt (19. Mai 2011)

Nur mal so in den Raum geworfen:
hängt die Sichtbarkeit nicht erst mal vom Transaktionsisolationslevel der DB ab, und somit auch wann in deinem Fall eine Transaktion geöffnet/geschlossen wird?


----------



## Gast2 (19. Mai 2011)

FArt hat gesagt.:


> Nur mal so in den Raum geworfen:
> hängt die Sichtbarkeit nicht erst mal vom Transaktionsisolationslevel der DB ab, und somit auch wann in deinem Fall eine Transaktion geöffnet/geschlossen wird?



Mhm das könnte sein, dass die 2 DB Aufrufe in 2 unterschiedlichen Transaktionen ablaufen, muss ich mal prüfen wie das bei dem Extended EntityManager abläuft.


----------



## Deadalus (24. Mai 2011)

Warum überhaupt der ganze Statefull quatsch? Ich bin mir ziemlich sicher, das du das was du hier vorhast auch mit Stateless Beans und einem default EntityManager umsetzen kannst. 


Sag mir doch bitte einmal fachlich was du da entwickeln willst. Also bitte keine technischen Details sondern sag einfach am besten aus Sicht des Benutzers was hier passieren soll.


----------



## Gast2 (25. Mai 2011)

Deadalus hat gesagt.:


> Warum überhaupt der ganze Statefull quatsch? Ich bin mir ziemlich sicher, das du das was du hier vorhast auch mit Stateless Beans und einem default EntityManager umsetzen kannst.



Weil ich einen Rich Client mit einer long running session hab.


----------



## Deadalus (25. Mai 2011)

SirWayne hat gesagt.:


> Weil ich einen Rich Client mit einer long running session hab.



Sorry aber das ist ein technisches Detail ich hatte dich eigentlich darum gebeten mir grob zu erklären was du fachlich machen willst. Ich seh keinen Grund den ganzen Zustandskram auch noch zusätzlich im EJB Container zu verwalten. 

Was du ja noch nicht mal wirklich tust, da deine SessionBeans nur Methoden und keinerlei Zustände besitzen.


----------



## FArt (26. Mai 2011)

Deadalus hat gesagt.:


> Sorry aber das ist ein technisches Detail ich hatte dich eigentlich darum gebeten mir grob zu erklären was du fachlich machen willst. Ich seh keinen Grund den ganzen Zustandskram auch noch zusätzlich im EJB Container zu verwalten.
> 
> Was du ja noch nicht mal wirklich tust, da deine SessionBeans nur Methoden und keinerlei Zustände besitzen.



Du hast Recht: man sollte auf SFSB verzichten, wenn das möglich ist. SLSB sind wesentlich einfacher zu handhaben, sind leichter zu verwalten und flexibler z.B. bzgl. Skalierung.

P.S.: Es gibt auch Status, der nicht direkt am Bean gehalten wird sondern einfach über den Kontext. Gehen wir mal davon aus, dass das hier ein einfaches, kleines Beispiel ist und wir nicht alle relevanten Stellen sehen können. Aus Erfahrung können wir aber tatsächlich auch davon ausgehen, dass die meisten SFSB unnötig sind und durch etwas besseres ersetzt werden könnten.


----------



## Gast2 (26. Mai 2011)

Das ist ein technisches Detail, wie die Archtiektur der Software ist, somit eine Prämisse für die Umstellung. Damit doch geklärt welcher EntityManager zu benutzen ist.


----------



## FArt (26. Mai 2011)

SirWayne hat gesagt.:


> Das ist ein technisches Detail, wie die Archtiektur der Software ist, somit eine Prämisse für die Umstellung. Damit doch geklärt welcher EntityManager zu benutzen ist.



Nachdem der EM (extended) von der Applikation gemanagt wird kann man dir hier m.E. nicht wirklich helfen, denn du kannst zwar Finder außerhalb der Transaktion aufrufen, aber bis jetzt ist ja nicht geklärt, wann die Daten transaktionell geschrieben wurden. Das wolltest du nach eigener Aussage noch klären.


----------



## Gast2 (26. Mai 2011)

FArt hat gesagt.:


> Nachdem der EM (extended) von der Applikation gemanagt wird kann man dir hier m.E. nicht wirklich helfen, denn du kannst zwar Finder außerhalb der Transaktion aufrufen, aber bis jetzt ist ja nicht geklärt, wann die Daten transaktionell geschrieben wurden. Das wolltest du nach eigener Aussage noch klären.



Ja ich bin noch dazu gekommen, ich muss noch überprüfen ob wirklich 2 Transaktionen im Spiel sind und ob es eine Möglichkeit gibt eine daraus zu machen.


----------



## Gast2 (26. Mai 2011)

Es ist ein rich client zu einer schrittweisen kalkulation mit sehr vielen Masken und Eingabeparameter und das Angebot wird am Ende committed oder nicht.


----------

