JPA und H2 Criteria

Hallo,

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 :slight_smile:

Hi,

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.

mm sehr misteriös :smiley: … ist ja nicht mal ne umfangreiches Query. Ich werde es nachher zuhause mal bei mir testen.

Kann es vll. am Datentyp „long“ liegen?
http://www.h2database.com/html/datatypes.html#bigint_type

Also gibt er dir was ohne die condition zurück?

ps. sry kann nicht editieren :wink:

Ohne Condition funktioniert alles wunderbar.

Ich habe nun ein simples Maven-Project erstellt. Da fällt genau dieser Test auf die Nase.

https://bitbucket.org/larmicBB/h2-criteria-test

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]

Hmm, da hast Du recht. Im echten System mit der MySQL habe ich eine Hibernate_Sequence-Tabelle.

edit: doch, das stimmt bei mir. Allerdings bekomme ich einen Log in der trace.db

org.h2.jdbc.JdbcSQLException: Tabelle „DEPENDING_SIMPLE“ nicht gefunden

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();
	}
}

[XML]<?xml version="1.0" encoding="UTF-8"?>


org.apache.openjpa.persistence.PersistenceProviderImpl
de.larmic.test.h2test.model.DependingEntity
de.larmic.test.h2test.model.SimpleEntity









[/XML]

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.

Eine aktualisierte Version habe ich eingecheckt…

habs nun auch nochmal mit In-Memory, wie in deinem Bsp. versucht … hat auch geklappt

“”

aber halt noch openJPA. .

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: "

Kenne mich mit OpenJPA leider nicht aus.

In die Startparameter einmal " -javaagent:/.jar" eintragen.
Also in Run-Configurations → VM Arguments

Ich warte nochmal solange mit dem ins Bett gehen, wenns nimmer solang dauert :stuck_out_tongue: :stuck_out_tongue:

Danke für die Hilfe.

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.

Großen Dank!

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.

Danke!

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.

okay, dann brauch ich nun nicht mehr drüber schauen. Aber interessantes Problem und nur so lernt man auch was dazu, wenns nicht klappt wie man denkt :slight_smile: :stuck_out_tongue: :wink:

So sieht das aus. :slight_smile: