ich habe ein Problem eine Criteria zu testen. Mit einer MySQL-DB funktioniert die Criteria. Mein Test nutzt eine H2, da ist die Ergebnisliste allerdings leer.
@Table(name = "Some")
public class SomeEntity {
...
}
@Entity
@Table(name = "Other")
public class OtherEntity {
...
@ManyToMany(fetch = FetchType.EAGER)
private List<SomeEntity> somes;
}```
Ich möchte nun alle OtherEntities finden, die irgendwo referenziert werden.
```private List<String> findDependencies(final long someEntityId) {
final CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
final CriteriaQuery<String> criteriaQuery = builder.createQuery(String.class);
final Root<OtherEntity> root = criteriaQuery.from(OtherEntity.class);
criteriaQuery.orderBy(builder.asc(root.get(OtherEntity_.topic)));
final Join<OtherEntity, SomeEntity> somes = root.join(OtherEntity_.somes);
final Path<Long> someIdPath = somes.get(SomeEntity_.id);
final Predicate condition = builder.equal(someIdPath, someEntityId);
criteriaQuery.select(root.get(OtherEntity_.topic)).where(condition);
return this.entityManager.createQuery(criteriaQuery).getResultList();
}```
Hat jemand einen Tipp?
Hast du mal in die Datenbanken geguckt, ob die irgendwie verschieden aufgebaut wurden (Was ich vll. eher bezweifel).
Ansonsten würde ich mal Teile von der Criteria z.b. orderBy etc. wegnehmen und schauen bis wohin er richtig arbeitet.
Ps. wenn ich zuhause bin kann ich das gern auch mal mit H2 probieren und schauen
an das OrderBy hatte ich schon gedacht. Das hat nicht geholfen. Die Datenbank sieht soweit ok aus. Es ist übrigens egal, ob ich eine Criteria oder eine NamedQuery verwende.
Die Where Bedingung sieht komisch aus. Die Entities kriegen bei mir beide die ID 1, aber in der where bedingung steht dann
[SQL]where
simpleenti2_.id=3[/SQL]
Sry gerade erst richtig nachhause gekommen ich habs mal die wichtigen Stellen schnell zusammenkopiert und ausgeführt,… muss auch gleich wieder weg,… hab OpenJPA + H2 benutzt…
private static EntityManager em;
public static void main(String[] args) {
EntityManagerFactory factory = Persistence
.createEntityManagerFactory("OpenJPAUnit");
em = factory.createEntityManager();
final SimpleEntity simpleEntity = createAndPersistSimple("simple");
createAndPersistDepending("depending", simpleEntity);
final CriteriaBuilder builder = em.getCriteriaBuilder();
final CriteriaQuery<Object> criteriaQuery = builder.createQuery(Object.class);
final Root<DependingEntity> root = criteriaQuery.from(DependingEntity.class);
// join
final Join<DependingEntity, SimpleEntity> join = root.join("simples");
final Path<Long> joinId = join.get("id");
criteriaQuery.select(root.get("value")).where(builder.equal(joinId, simpleEntity.getId()));
final List<Object> simples = em.createQuery(criteriaQuery).getResultList();
System.out.println(simples.size());
System.out.println(simples.contains("simple"));
}
private static SimpleEntity createAndPersistSimple(final String value) {
final SimpleEntity simpleEntity = new SimpleEntity();
simpleEntity.setValue(value);
saveObject(simpleEntity);
return simpleEntity;
}
private static DependingEntity createAndPersistDepending(final String value, final SimpleEntity simpleEntity) {
final DependingEntity dependingEntity = new DependingEntity();
dependingEntity.setValue(value);
dependingEntity.getSimples().add(simpleEntity);
saveObject(dependingEntity);
return dependingEntity;
}
public static void saveObject(Object obj) {
em.getTransaction().begin();
em.persist(obj);
em.getTransaction().commit();
}
}
Ergebnis:
1 (also das eine Objekt in der Liste)
false
Select:> executing prepstmnt 17679958 SELECT t0.value FROM Depending t0 INNER JOIN Depending_Simple t1 ON t0.id = t1.DEPENDINGENTITY_ID INNER JOIN Simple t2 ON t1.SIMPLES_ID = t2.id WHERE (t1.SIMPLES_ID = ?) [params=?]
Mal ne andere Sache der Test muss übrigens fehlschlagen … du suchst den root.get(“value”) und der Root ist das “DependingEntity” welches “depending” als Variable hat.
Da geht “Assert.assertTrue(simples.contains(“simple”));” in die Hose
Oder bin ich jetzt einfach zu kaputt und sollte lieber ins Bett?^^
Danke Dir für den ausführlichen Test. Du hast recht, der letzte Check muss schief gehen, aber da kam ich nicht hin. Irgendwie scheint JPA in Verbindung mit H2 Embedded keine Join-Tables bei mir zu erstellen.
Welche Dependencies verwendest Du mit OpenJPA? Ich bekomme immer ein
<openjpa-2.2.2-r422266:1468616 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "
Ich habe das mit dem Agent über ein OpenJPA-Maven-Plugin gelöst und bekomme nun org.apache.openjpa.persistence.PersistenceException: org.apache.openjpa.jdbc.kernel.exps.Variable cannot be cast to org.apache.openjpa.kernel.exps.Val in genau diesem Test.
Ich habe alles eingecheckt.
Ich würde mich freuen, wenn Du da noch mal drüber schaust, denke aber, dass Schlafen wichtig ist. Und meine Welt explodiert nicht, wenn es heute nicht mehr läuft.
So, ich habe die Vermutung, dass es an der Persistence-Unit in Verbindung mit Hibernate liegt. Gegen die lokale MySQL läuft es in dem Test auch nicht gegen die MySQL.
Ich habe die aktuellste Version committed. Man kann nun im Test zwischen den einzelnen PUs wechseln.
UPDATE: Ich habe nun eclipse-link ausprobiert. Damit klappt es problemlos. Hat also irgendetwas mit der PersistenceUnit zu tun.
Hmm, bei mir geht es jetzt auch. Ist alles eingecheckt, wenn es wer mal brauchen sollte. Der ist anscheinend komisch bei einer Assertion rausgesprungen.
Ich habe das noch einmal analysiert. Es fehlte auf der Transaktion der commit (im Test). Das wird dann im EM nicht gecached und macht deshalb Probleme.