# JPA Interfaces annotieren



## mephi (3. Dez 2008)

Ist es eigentlich möglich auch Interfaces zu annotieren? Bei Google hab ich nichts dazu gefunden. Die Annotations im Interface werfen auch keine Fehler, aber in der persistence.xml muss ich ja meine Klassen und nicht meine Interfaces angeben.
Ich hab aktuell das Problem dass ich gegen bestehende Interfaces programmiere und ich eine Fehlermeldung bekommen dass er den Typ eines Feldes nicht kennt.(wobei eine Umstellung aller Typen auf die implementierten Klassen auch nichts gebracht hat, aber es kam eine andere ähnliche Fehlermeldung)


----------



## byte (3. Dez 2008)

Wenn Du gegen Interfaces programmierst (was sehr löblich ist), dann musst Du im Mapping explizit die Implementierung zur Laufzeit angeben. Das läuft meistens über ein Attribut _targetEntity_, das eine Klasse als Wert akzeptiert.


----------



## mephi (3. Dez 2008)

wieso denn zur Laufzeit? Ich kenn ja meine Implementierungen 
Geht es anders nicht oder ist das nur der "schöne" weg?


----------



## byte (3. Dez 2008)

Du hast mich mißverstanden. Das "Laufzeit" bezog sich nicht aufs "angeben" sondern auf die "Implementierung". 
Für gewöhnlich hat man nur eine Implementierung und die gibt man im Attribut _targetEntity_ an.

Also z.B.:

```
@OneToMany(targetEntity = FooImpl.class)
@JoinColumn(...)
@IndexColumn(...)
private List<Foo> foos;
```


----------



## mephi (3. Dez 2008)

ok sag das doch gleich 

aber die annotations müssen dann schon in die Implementierung und nicht ins interface?


----------



## byte (3. Dez 2008)

Habs um ehrlich zu ein noch nie ausprobiert, die Interfaces mit JPA zu annotieren.

Aber ganz ehrlich: Selbst wenns ginge, würde ich es nicht machen. Aus folgenden Gründen:

1. Aus o.g. Gründen hätten dann die Interfaces Abhängigkeiten zur Implementierung.
2. Ich möchte meine Interfaces nicht mit technischen Details (Persistenz) verschmutzen.
3. Man gerät mit JPA desöfteren an die Grenzen, wo man dann auf die Implementierungserweiterungen zurückgreift (bsp: DELETE_ORPHAN). Auch diese Abhängigkeit (zu Hibernate) möchte ich nicht im Interface haben.

Bei uns liegt das Modell (Interfaces) in einem eigenen Java-Projekt und hat keine Abhängigkeiten zu irgendwas ausser dem JDK.


----------



## mephi (3. Dez 2008)

Hast mich überzeugt.
Das ganz macht ziemlich Kopfschmerzen. Ich hab ja gedacht es sei eine Glaubensfrage ob man die Annotations direkt an die Felder macht oder an die Getter/Setter. Aber es macht ja schon ein Unterschied ob ichs an den Getter ODER an den Setter mache...


----------



## maki (3. Dez 2008)

Mach sie doch an die Felder.


----------



## mephi (3. Dez 2008)

Ich hatte bisher am getter:


```
@ManyToOne(targetEntity=UserImpl.class)
@JoinColumn(nullable=false)
public IUser getUser()
```

da kommt:
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: SessionImpl.user

und beim feld:
Caused by: org.hibernate.MappingException: Could not determine type for: IUser, at table: session, for columns: [org.hibernate.mapping.Column(user)]


und ich ruf das ganze so auf:


```
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate-unit");
	        EntityManager em = emf.createEntityManager();
	        em.getTransaction().begin();
	        

	        
	        IUser u = new UserImpl();
	        u.setId("test"); 
	        em.merge(u);
	        
	        ISession s = new SessionImpl();
	        s.setId("hallo2");
	        s.setUser(u);
	        em.merge(s);
	        
	        em.getTransaction().commit();
	        em.close();
```


----------



## mephi (3. Dez 2008)

ok, die annotation @id hatte ich noch am setter. man sollte das wohl nicht mixen. habs nun am feld und es geht.


----------

