Hey,...
so in den letzten Wochen haben sich ein paar Fragen ergeben, die ich nun gesammelt hier in dem Thread bearbeiten wollte... ich hoffe das is okay
ich kennzeichne die Frage mal immer "fett", dass man sie unterscheiden kann.
DTO vs. Persistenz Objekte
Szenario: Man will eine Liste von Personen in z.b. JSF anzeigen und diese dann auch bearbeiten und ggf. speichern können. (Man brauch aber jeweils nur eine Teilmenge der Daten). Dazwischen ist eine LocalBean / Stateless, welche Transaction Einstellungen besitzt (Required).
Ausgehend von z.b. so einer Entity- Klasse und man braucht nur alle Vereine, alter, name:
Meine Frage ist, was ist hier die beste Lösung,...
A. Man gibt das Persistenz Objekt nach oben, lädt nur die Daten die man dafür braucht(lazy load). Bearbeitet das Detached- Objekt oben und gibt es wieder runter und behandelt ggf. Exceptions durch Optimistic locking...
B. Man überdenkt seine Struktur, ob man wirklich die ganzen Sachen in der Person braucht
C. Man erzeugt ein DTO, welches nur die Daten, die man wirklich braucht hält. Problem dabei ist, man muss halt die Version mitschleifen und Objekte hin und her konvertieren.
D. Eure Vorschläge...
JPA Annotations
Ich habe ein wenig gegooglet, wohin die Annotations nun wirklich kommen,... irgendwie sagt die eine Seite so, die andere so... wie immer halt
Daher wollte ich hier mal fragen, wie ihr das seht... ich glaub von Maki hab ich letzten gelesen "FIELD!!!"^^
- Alles auf einen Blick bei Field- Annotation
- Kein Getter/Setter gespamme bei Field- Annotation
- Im Getter kann was anderes passieren, als nur die Rückgabe des Wertes... was aber auch wiederum als positiv angesehn wurde von manchen
- Der Zugriff "direkt" auf Attribute is böse
- Probleme bei manchen JPA Implementierungen
Einig waren sich nur alle, dass man nicht mixen sollte
wie gesagt, das sind so Meinungen, die ich gefunden habe... daher wollte ich mal fragen, wie ihr das macht und warum.
Hibernate vs. OpenJPA/EclipseLink etc.
Ich hatte schon einmal festgestellt, dass Hibernate sich bei ManyToMany anders verhält, als es andere Implementierungen tun.
Ich hab die Annotations gerade an den Getter/Settern, aber wie gesagt dafür hab ich ja die Diskussion auf gemacht
Beispiel um den Unterschied zu zeigen,... nicht auf Einzelheiten achten:
Person:
Verein:
Main- Methode:
persistence.XML von Hibernate:
Persistence XML von OpenJPA:
Verhalten:
OpenJPA löscht die ManyToMany- Beziehung einfach direkt, obwohl noch Abhängigkeiten in der Beziehungstabelle bestehen.
Hibernate schmeißt hingegen wenn man nix am CascadeMode ändert eine " org.hibernate.exception.ConstraintViolationException".
Weiterhin habe ich gelesen, dass bei JPA halt beide Seiten die Owner sind.
ManyToMany (Java EE 5 SDK)
Nun ist die Frage, wie ich das Verhalten bei OpenJPA anpassen kann.
Lösungsvorschläge:
A. Ich schau auf dem Objekt was ich löschen will, ob noch Einträge in der Liste vorhanden sind und schmeiße ggf. Exception selber
B. Ich mach ne SQL Abfrage mit Count und schau ob dort noch Einträge vorhanden sind und schmeiße ne Exception
Exceptionhandling JSF + EJB
Da man bei EJB meistens eh EJB NestedExceptions bekommt, ist es in JSF eine gute Lösung einfach alles hochzuschmeißen sich ggf. ein ExceptionTranslater zubauen? Dieser iteriert die Nested Exceptions durch und filtert die "richtigen" Exceptions, verpackt diese und wirft sie an einen Exception Handler der in der Web.xml eingestellt wurde?
Wenn Nein, wie macht ihr das ? Weil ich finde Exception kreuz und quer im Code zu behandeln is irgendwie auch nicht so toll / übersichtlich^^
so in den letzten Wochen haben sich ein paar Fragen ergeben, die ich nun gesammelt hier in dem Thread bearbeiten wollte... ich hoffe das is okay
DTO vs. Persistenz Objekte
Szenario: Man will eine Liste von Personen in z.b. JSF anzeigen und diese dann auch bearbeiten und ggf. speichern können. (Man brauch aber jeweils nur eine Teilmenge der Daten). Dazwischen ist eine LocalBean / Stateless, welche Transaction Einstellungen besitzt (Required).
Ausgehend von z.b. so einer Entity- Klasse und man braucht nur alle Vereine, alter, name:
Java:
@Entity
public class Person {
@Version
private Long version;
private Long id;
private String name;
private int alter;
private String lieblingsFarbe;
private List<Vereine> vereine;
private List<Hobby> hobbys;
private List<Person> freunde;
Meine Frage ist, was ist hier die beste Lösung,...
A. Man gibt das Persistenz Objekt nach oben, lädt nur die Daten die man dafür braucht(lazy load). Bearbeitet das Detached- Objekt oben und gibt es wieder runter und behandelt ggf. Exceptions durch Optimistic locking...
B. Man überdenkt seine Struktur, ob man wirklich die ganzen Sachen in der Person braucht
C. Man erzeugt ein DTO, welches nur die Daten, die man wirklich braucht hält. Problem dabei ist, man muss halt die Version mitschleifen und Objekte hin und her konvertieren.
D. Eure Vorschläge...
JPA Annotations
Ich habe ein wenig gegooglet, wohin die Annotations nun wirklich kommen,... irgendwie sagt die eine Seite so, die andere so... wie immer halt
Daher wollte ich hier mal fragen, wie ihr das seht... ich glaub von Maki hab ich letzten gelesen "FIELD!!!"^^
- Alles auf einen Blick bei Field- Annotation
- Kein Getter/Setter gespamme bei Field- Annotation
- Im Getter kann was anderes passieren, als nur die Rückgabe des Wertes... was aber auch wiederum als positiv angesehn wurde von manchen
- Der Zugriff "direkt" auf Attribute is böse
- Probleme bei manchen JPA Implementierungen
Einig waren sich nur alle, dass man nicht mixen sollte
wie gesagt, das sind so Meinungen, die ich gefunden habe... daher wollte ich mal fragen, wie ihr das macht und warum.
Hibernate vs. OpenJPA/EclipseLink etc.
Ich hatte schon einmal festgestellt, dass Hibernate sich bei ManyToMany anders verhält, als es andere Implementierungen tun.
Ich hab die Annotations gerade an den Getter/Settern, aber wie gesagt dafür hab ich ja die Diskussion auf gemacht
Beispiel um den Unterschied zu zeigen,... nicht auf Einzelheiten achten:
Person:
Java:
@Entity
public class Person {
private Long id;
private String name;
private int alter;
private List<Verein> vereine;
protected Person(){
}
public Person(String name, int alter){
this.alter = alter;
this.name = name;
this.vereine = new ArrayList<Verein>();
}
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PERSON_SEQ")
@SequenceGenerator(name="PERSON_SEQ",sequenceName="PERSON_SEQ",initialValue = 1,allocationSize=1)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAlter() {
return alter;
}
public void setAlter(int alter) {
this.alter = alter;
}
@ManyToMany()
public List<Verein> getVereine() {
return vereine;
}
public void setVereine(List<Verein> vereine) {
this.vereine = vereine;
}
public void addVerein(Verein verein){
this.vereine.add(verein);
verein.addPerson(this);
}
}
Verein:
Java:
@Entity
public class Verein {
private Long id;
private List<Person> mitglieder;
private String vereinsName;
protected Verein(){
}
public Verein(String vereinsName){
this.vereinsName = vereinsName;
this.mitglieder = new ArrayList<Person>();
}
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="VEREIN_SEQ")
@SequenceGenerator(name="VEREIN_SEQ",sequenceName="VEREIN_SEQ",initialValue = 1,allocationSize=1)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToMany(mappedBy="vereine")
public List<Person> getMitglieder() {
return mitglieder;
}
public void setMitglieder(List<Person> mitglieder) {
this.mitglieder = mitglieder;
}
public String getVereinsName() {
return vereinsName;
}
public void setVereinsName(String vereinsName) {
this.vereinsName = vereinsName;
}
public void addPerson(Person person) {
this.mitglieder.add(person);
}
}
Main- Methode:
Java:
public class Starter {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("HibernateUnit");
EntityManager em = factory.createEntityManager();
init(em);
deleteVerein(em);
}
private static void deleteVerein(EntityManager em) {
em.getTransaction().begin();
em.remove(em.find(Verein.class, 1L));
em.getTransaction().commit();
}
private static void init(EntityManager em) {
em.getTransaction().begin();
Person person = new Person("Hans",45);
Verein verein = new Verein("Verein1");
Verein verein2 = new Verein("Verein2");
person.addVerein(verein2);
person.addVerein(verein);
em.persist(verein2);
em.persist(verein);
em.persist(person);
em.getTransaction().commit();
}
}
persistence.XML von Hibernate:
Java:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="HibernateUnit" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>model.Person</class>
<class>model.Verein</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
<property name="hibernate.connection.url" value="jdbc:h2:D:\\test\testdb" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
Persistence XML von OpenJPA:
Java:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="OpenJPAUnit" >
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>model.Person</class>
<class>model.Verein</class>
<properties>
<property name="openjpa.ConnectionDriverName" value="org.h2.Driver" />
<property name="openjpa.ConnectionURL" value="jdbc:h2:D:\\test\testdb" />
<property name="openjpa.ConnectionUserName" value="sa" />
<property name="openjpa.ConnectionPasswort" value="" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='drop,add')"/>
</properties>
</persistence-unit>
</persistence>
Verhalten:
OpenJPA löscht die ManyToMany- Beziehung einfach direkt, obwohl noch Abhängigkeiten in der Beziehungstabelle bestehen.
Hibernate schmeißt hingegen wenn man nix am CascadeMode ändert eine " org.hibernate.exception.ConstraintViolationException".
Weiterhin habe ich gelesen, dass bei JPA halt beide Seiten die Owner sind.
ManyToMany (Java EE 5 SDK)
Nun ist die Frage, wie ich das Verhalten bei OpenJPA anpassen kann.
Lösungsvorschläge:
A. Ich schau auf dem Objekt was ich löschen will, ob noch Einträge in der Liste vorhanden sind und schmeiße ggf. Exception selber
B. Ich mach ne SQL Abfrage mit Count und schau ob dort noch Einträge vorhanden sind und schmeiße ne Exception
Exceptionhandling JSF + EJB
Da man bei EJB meistens eh EJB NestedExceptions bekommt, ist es in JSF eine gute Lösung einfach alles hochzuschmeißen sich ggf. ein ExceptionTranslater zubauen? Dieser iteriert die Nested Exceptions durch und filtert die "richtigen" Exceptions, verpackt diese und wirft sie an einen Exception Handler der in der Web.xml eingestellt wurde?
Wenn Nein, wie macht ihr das ? Weil ich finde Exception kreuz und quer im Code zu behandeln is irgendwie auch nicht so toll / übersichtlich^^
Zuletzt bearbeitet: