# CDI Ein Objekt erstellen



## OnDemand (15. Okt 2015)

Hallo zusammen,

nun bin ich mal wieder am programmieren, hatte einiges zu tun. Nun komm ich gleich wieder zu einem Problem; ich habe eine Klasse, von der ich hunderteObjekte brauche um sie in einer anderen Methode zu verarbeiten.

Folgendes:

```
@Stateless
class Produkt {

//hat Eigenschaften und deren getter & setter

}
```

in dieser Klasse, möchte ich  (verschiedene) Objekte erstellen

```
class LeseTextdatei{

@EJB
Produkt produkt
@EJB
Speichern speichern

//lesezeugs
// name = aus Datei
produkt.setName(name);

list.add(produkt);
//nach dem die DAtei gelesen ist
speichern.persist(list);
}
```

In dieser Klasse/Methode soll die liste durchgegangen werden und jedes Produkt gespeichert werden

```
class Speichern{
@EJB
Produkt produkt;

private void persist(List list){
for(int i =0; i<=list.sitze-1;i++{
produkt= list.get(i);

//produkt speichern
}
}

}
```
Das Problem ist, dass in meiner Datenbank längst nicht alle Produkte ankommen, von ca 833 (zeigt auch die Menge der List) werden nur 134 gespeichert. Außerdem habe ich eine Prüfung, ob Entities schon in der Datenbank sind, ständig wird mir angezeigt, dass der Artikel bereits drin ist (was aber nicht so ist). Daher meine Vermutung, dass meine Produkt-Objekte nicht 833 verschiedene sind, sondern diese irgendwie recycled werden!?

Meine eigentliche Frage: Wenn ich ein Objekt wie oben über CDI hole, ist das wirklich das gleichen, als wenn ich eines mit new erzeuge? WAs ist der Unterschied zwischen @EJB und @Inject

Ich hoffe mir kann jemand helfen!


----------



## Dompteur (15. Okt 2015)

Mit @Stateless bei der Klasse Produkt gibst du an, dass deine Objekte geshared werden können. Also eigentlich das, was du vermutest. Du greifst immer wieder auf gleiche Objekte zu.
Du benötigst @stateful. Damit wird jedes Mal eine eigene Objektinstanz erzeugt.


----------



## OnDemand (15. Okt 2015)

Oh man...Ich danke dir! Wer ich morgen gleich testen! Weißt du den unterschied zwischen  ejb und inject?


----------



## OnDemand (15. Okt 2015)

Noch ne frage...sind dem Session beans überhaupt dafür gedacht in der Business logic benutzt zu werden? Mein Beispiel ist zum beispiel völlig unabhängig von irgendwelchen views oder Benutzereingaben. Das wird über nen timer gestartet. Sessionbean klingt danach, als nutzt man diese im Zusammenhang mit views und usersessions. 

Kann man neue  Objekte nicht auch herkömmlich per new erstellen?


----------



## stg (15. Okt 2015)

Hast du immer noch kein Buch zu den Grundlagen durchgelesen, wie ich es dir schon gefühlte tausend Mal ans Herz gelegt habe?



NicoDeluxe hat gesagt.:


> ..sind dem Session beans überhaupt dafür gedacht in der Business logic benutzt zu werden?



Andersrum, die BusinessLogic wird (oft größtenteils) in SessionBeans implementiert. In SessionBeans sollte nichts (!) anderes als BusinessLogic vorhanden sein. 



> Sessionbean klingt danach, als nutzt man diese im Zusammenhang mit views und usersessions.


Es ist unklar, was genau du nun tatäschlich mir views und usersessions meinst. Vermutlich weißt du das aber selbst nicht so genau. SessionBeans haben jedenfalls rein gar nichts mit der HTTPSession oder dergleichen zu tun, falls du das meinen solltest.



> Kann man neue  Objekte nicht auch herkömmlich per new erstellen?


Klar _kann_ man das. Was du hier aber genau vorhast, bleibt schleierhaft. Der gepostete Code ist (soweit ich ungefähr erahnen kann, was du vorhast) nicht zu retten...




NicoDeluxe hat gesagt.:


> Meine eigentliche Frage: Wenn ich ein Objekt wie oben über CDI hole, ist das wirklich das gleichen, als wenn ich eines mit new erzeuge? WAs ist der Unterschied zwischen @EJB und @Inject


Nein, das ist nicht das gleiche. Sowohl per @EJB als auch per @Inject bekommst du vom Container verwaltete Instanzen. Mit @EJB injizierst du SessionBeans, mit @Inject jedwede vom CDI Container gemanaged-ten Beans. Das können auch SessionBeans sein, aber auch sonst eigentlich nahezu alles. CDI ist da recht stark. @EJB ist Teil der EJB Spezifikation, @Inject ist Teil der CDI Spezifikation.

Den Vorschlag von Dompteur kannst du im Übrigen auch getrost vergessen. Stateful SessionBeans sind dafür da, damit du in einer SessionBean einen Zustand vorhalten kannst, etwa über mehrere aufeinanderfolgende Transaktionen hinweg mit einem erweiterten PersistentContext o.Ä. Meist braucht man sie aber eigentlich gar nicht, sondern arbeitet besser mit zustandslosen Services und lässt den Zustand beim Client, also z.B. einer JSF- oder CDI-managed Bean. Der Gebrauch von (vielen) Statefull Beans deutet _meistens _auf eine schlechte Architektur hin.


----------



## stg (15. Okt 2015)

Übrigens, du kannst auch per CDI "ganz normale Objekte" erstellen und per @Inject injizieren. Dazu schreibst du einen Producer, das ist quasi die CDI implementierung des Factory patterns. Aber da es sich bei deinem Produkt um ein stinknormales DTO zu handeln scheint, brauchst du solche Spielchen gar nicht. Erstelle (in diesem Fall ausnahmsweise mal!) deine Objekte von Hand mit _new _und übergib sie hinterher (einzeln oder die ganze Liste auf einmal, je nachdem) deinem Service zum speichern..


----------



## OnDemand (17. Okt 2015)

Hab mein Buch nochmal durchgewälzt, in der Tat habe ich SessionBeans auf HTTP Sessions bezogen und wenn es um Clients ging, dachte ich es geht um einen Browser, aber ein Client kann ja auch mal eine andere Bean sein. Das sollte man schon mal wissen...

Dennoch verstehe ich nicht, warum CDI und EJB. Ich habe zb im Buch ne Klasse "Test" diese ist mit @stateful annotiert, wird aber mit @Inject injiziert.  Ich denke Inject ist CDI, wie kann das dann ne EJB injizieren....ihr seht...große Verwirrung! Das man zu Anfang sehr verwirrt ist steht auch so im Buch übrigens...das beruhigt mich^^


----------



## stg (20. Okt 2015)

CDI und EJB sind zwei unterschiedliche Baustellen. CDI standardisiert die Dependency Injection und kann quasi alles, was sich an diese Standards hält in nahezu alles, was sich an diese Standards hält, injizieren. Dazu zählen unter anderem EJBs .... eigentlich. Also in den meisten einfachen Fällen jedenfalls. Schwieriger wird es, wenn du mit CDI zum Beispiel remote-EJBs injizieren willst, oder du für einen Service verschiedene Implementierungen bereitstellst. Glücklicherweise stellt EJB einen eigenen Mechanismus zur Dependency Injection bereit über die @EJB Annotation. Und wenn du da mal genauer nachschaust, wirst du feststellen, dass du der @EJB Annotation zusätzliche Attribute übergeben kannst (und damit z.B. das zuvor Gesagte umsetzen kannst), der CDI @Inject Annotation aber nicht.

- @EJB ist für die Injektion von EJBs, und zwar ausschließlich. Du kannst hiermit deutlich feiner definieren, was von wo wohin injiziert werden soll, aber eben nur für EJBs.
- Über CDI kannst du mittels @Inject alles injizieren, was sich an die hierfür definierten Konventionen hält. 

Du machst zu Beginn jedenfalls nichts falsch, wenn du ausschließlich CDI für die Injeciton benutzt. Wenn du dann wirklich bald auf einen Fall stößt, für den das nicht mehr (ohne weitere Zuarbeit) ausreicht, kannst du dir immer noch über alles Weitere Gedanken machen.


----------



## OnDemand (20. Okt 2015)

Okayyyy, danke stg! Noch ne blöde Frage. Ein ganz normales POJO, sollte welche Annotation haben, damit ich davon hunderte verschiedene erstellen kann? (oder erstelle ich ein POJo normal per new?)
Hab mir ein Online-Shop-Tutorial von Oracle angeschaut, da werden Pojos nur mit new erzeugt und nicht injiziert.


----------



## stg (20. Okt 2015)

Kommt drauf an, was du damit vorhast 
Aber ich hatte ja schon geschrieben, dass ich aufgrund deiner bisher hier geposteten Ansätze davon ausgehe, dass du in diesem Fall einfach deine Objekte selbst mit _new_ erstellen solltest.


----------



## OnDemand (25. Okt 2015)

Hi, so nun klappt es! Ich glaube ich habe wirklich zu viel durcheinander geworfen. LKangsam aber sicher kommt Licht ins Dunkel. Wir haben in ein paar Wochen einen 5 tägigen Kurs für den JavaEE Einstieg, mal sehen ob ich den besuchr  (teuer wie sau), aber bestimmt hilfreich.


----------

