Derby/JavaDB Beispiel funktioniert nur einmal

hirsra

Aktives Mitglied
Hallo.

Ich habe ein Eclipselink(v2.6))-Beispiel mit Derby(v10.13.1.1) von der Seite http://www.vogella.com/tutorials/JavaPersistenceAPI/article.html durch Copy/Paste in meine eigene Entwicklungsumgebung installiert. Ich habe ein paar unkritische Änderungen vorgenommen, z.b. Ort der DB. Das Beispiel führt JUnit-Tests durch.

Beim ersten Ausführen der JUnit-Tests laufen alle Tests erfolgreich durch. Ab dem zweiten Versuch schlägt der Test checkFamily fehlt. Wenn ich die Datenbank lösche funktioniert wieder der erste Test, jeder weitere schlägt fehl.

Wenn ich mir die Tabelle anschaue scheint die Beziehung der Personen zur Familiy nicht gespeichert zu werden.

Kann mir jemand sagen warum, bzw. wie ich den Fehler beheben kann?

Nachfolgend die drei Klassen des Beispiels.

Java:
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Family {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;
    private String description;

    @OneToMany(mappedBy = "Family")
    private final List<Person> members = new ArrayList<Person>();

    public int getId() {
        return this.id;
    }

    public void setId(final int id) {
        this.id = id;
    }

    public String getDescription() {
        return this.description;
    }

    public void setDescription(final String description) {
        this.description = description;
    }

    public List<Person> getMembers() {
        return this.members;
    }

}

Java:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Job {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;
    private double salery;
    private String jobDescr;

    public int getId() {
        return this.id;
    }

    public void setId(final int id) {
        this.id = id;
    }

    public double getSalery() {
        return this.salery;
    }

    public void setSalery(final double salery) {
        this.salery = salery;
    }

    public String getJobDescr() {
        return this.jobDescr;
    }

    public void setJobDescr(final String jobDescr) {
        this.jobDescr = jobDescr;
    }

}

Java:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class JpaTest {

    private static final String PERSISTENCE_UNIT_NAME = "people";
    private EntityManagerFactory factory;

    @Before
    public void setUp() throws Exception {

        this.factory = Persistence.createEntityManagerFactory(JpaTest.PERSISTENCE_UNIT_NAME);

        final EntityManager em = this.factory.createEntityManager();

        // Begin a new local transaction so that we can persist a new entity
        em.getTransaction().begin();

        // read the existing entries
        final Query q = em.createQuery("select m from Person m"); //$NON-NLS-1$
        // Persons should be empty

        // do we have entries?
        final int size = q.getResultList().size();
        final boolean createNewEntries = q.getResultList().isEmpty();

        // No, so lets create new entries
        if (createNewEntries) {
            Assert.assertTrue(q.getResultList().size() == 0);
            final Family family = new Family();
            family.setDescription("Family for the Knopfs");
            em.persist(family);
            for (int i = 0; i < 40; ++i) {
                final Person person = new Person();
                person.setFirstName("Jim_" + i);
                person.setLastName("Knopf_" + i);
                em.persist(person);
                // now persists the family person relationship
                family.getMembers().add(person);
                em.persist(person);
                em.persist(family);
            }
        }

        // Commit the transaction, which will cause the entity to
        // be stored in the database
        em.getTransaction().commit();

        // It is always good practice to close the EntityManager so that
        // resources are conserved.
        em.close();

    }

    @Test
    public void checkAvailablePeople() {

        // now lets check the database and see if the created entries are there
        // create a fresh, new EntityManager
        final EntityManager em = this.factory.createEntityManager();

        // Perform a simple query for all the Message entities
        final Query q = em.createQuery("select m from Person m");

        // We should have 40 Persons in the database
        Assert.assertEquals(40, q.getResultList().size());

        em.close();
    }

    @Test
    public void checkFamily() {
        final EntityManager em = this.factory.createEntityManager();
        // Go through each of the entities and print out each of their
        // messages, as well as the date on which it was created
        final Query q = em.createQuery("select f from Family f");

        // We should have one family
        Assert.assertTrue(q.getResultList().size() == 1);

        final Family family = (Family) q.getSingleResult();
        final int noOfMembers = family.getMembers().size();
        // with 40 persons
        Assert.assertEquals(40, noOfMembers);
        em.close();
    }

    @Test(expected = javax.persistence.NoResultException.class)
    public void deletePerson() {
        final EntityManager em = this.factory.createEntityManager();
        // Begin a new local transaction so that we can persist a new entity
        em.getTransaction().begin();
        final Query q = em
                .createQuery("SELECT p FROM Person p WHERE p.firstName = :firstName AND p.lastName = :lastName");
        q.setParameter("firstName", "Jim_1");
        q.setParameter("lastName", "Knopf_!");
        final Person user = (Person) q.getSingleResult();
        em.remove(user);
        em.getTransaction().commit();
        final Person person = (Person) q.getSingleResult();
        // Begin a new local transaction so that we can persist a new entity

        em.close();
    }
}
 

stg

Top Contributor
Der Test schlägt fehl ... du bekommst also sicherlich auch eine Fehlermeldung?!
Außerdem wäre die andere Seite deines Mappings auf der Seite "Person" interessant.

Schau dir zudem mal an, was persist() überhaupt genau bewirkt. Das scheinst du noch nicht verstanden zu haben.
 

hirsra

Aktives Mitglied
Ups. Ja die Klasse Person habe ich vergessen. Hier ist sie.

Java:
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private String id;
    private String firstName;
    private String lastName;

    private Family family;

    private String nonsenseField = "";

    private List<Job> jobList = new ArrayList<Job>();

    public String getId() {
        return this.id;
    }

    public void setId(final String Id) {
        this.id = Id;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(final String firstName) {
        this.firstName = firstName;
    }

    // Leave the standard column name of the table
    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(final String lastName) {
        this.lastName = lastName;
    }

    @ManyToOne
    public Family getFamily() {
        return this.family;
    }

    public void setFamily(final Family family) {
        this.family = family;
    }

    @Transient
    public String getNonsenseField() {
        return this.nonsenseField;
    }

    public void setNonsenseField(final String nonsenseField) {
        this.nonsenseField = nonsenseField;
    }

    @OneToMany
    public List<Job> getJobList() {
        return this.jobList;
    }

    public void setJobList(final List<Job> nickName) {
        this.jobList = nickName;
    }

}
 

hirsra

Aktives Mitglied
Hier noch die die Fehlermeldung:
java.lang.AssertionError: expected:<40> but was:<0>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at test.de.jpa.vogella.relationship.JpaTest.checkFamily(JpaTest.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.extensions.cpsuite.ClasspathSuite.run(ClasspathSuite.java:205)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
 

stg

Top Contributor
Du hast sehr viele Variablen "final" deklariert. Das ist in der Vorlage nicht so. Kann es daran liegen?

Nein.

private Family family;
@OneToMany(mappedBy = "Family")

Beachte Groß- und Kleinschreibung.

Du mischt außerdem Field- und Property-basierten Zugriff. Ob das Probleme bereitet müsste ich selbst schauen, schön ist es jedenfalls nicht.
 

hirsra

Aktives Mitglied
@stq: Danke für die Hinweise mit der Groß- und Kleinschreibung und dem Mischen von Feld- und Property-basiertem Zugriff. Das ist in dem Beispiel so. Ich werde das bei mir aber ändern.

Das Beispielprogramm habe läuft bei mir jetzt bei jeden Aufruf ohne Fehler durch. Alles was ich gemacht habe ist in der Klasse JpaTest beim Setzen der Daten für die Person das Attribut 'family' durch den Aufruf person.setFamily(family) belegen.
Beim ersten Test(mit leerer DB) wurde ja die Family mit allen Personen initialisiert und das Array mit dem Familienmitgliedern auch gefüllt. Aber - und das verstehe ich nicht - offensichtlich wurde dieses Array nicht "persistiert", sondern beim 'select' mit einem 'select' aus der Person-Tabelle gefüllt.

Habe ich das richtig interpretiert?
 

hirsra

Aktives Mitglied
Noch eine abschließende Bemerkung: Der erste JUnit-Test funktioniert weil die Familiy im Cache steht, mit den Verknüpfungen zur Person, bzw. umgekehrt. Wird der Cache vor checkFamiliy() gelöscht schlägt schon der Start der Tests fehl.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W jpmdbc Problem -Beispiel funktioniert nicht Datenbankprogrammierung 9
S Beispiel-Blockchain + GUI mit Java erstellen Datenbankprogrammierung 0
Y MySQL Eclipselink Insert JSF Beispiel gesucht Datenbankprogrammierung 2
P Probleme mit meinem 1. Hibernate Beispiel Datenbankprogrammierung 3
B Beispiel für sicheres DBUsername/DBPassword handling Datenbankprogrammierung 4
B H2 Database Beispiel Source Code Datenbankprogrammierung 8
-horn- [Anfänger] Ein einfaches Beispiel für Abfrage von MxSQL? Datenbankprogrammierung 8
F Hibernate mit MySQL Beispiel und Timestamp Datenbankprogrammierung 6
M Beispiel zur Abfrage einer lokalen PostgresDB in Java! Datenbankprogrammierung 4
Auf MySql Datenbank zugreifen funktioniert nicht Datenbankprogrammierung 8
Warum funktioniert MySQL nicht Datenbankprogrammierung 8
S Das printen der Ausgabe des Oracle-SQL-Statements in der Java-Eclipse-Konsole funktioniert nicht Datenbankprogrammierung 6
S Datenbankprogrammierung in Java unter NetBeans 12 funktioniert nicht! Datenbankprogrammierung 1
D JPA gleiche methode funktioniert an einer Stelle, an der anderen nicht Datenbankprogrammierung 3
J Firebase KeepSynced funktioniert nicht Datenbankprogrammierung 0
L SQL-Statement INSERT INTO ON DUPLICATE KEY UPDATE funktioniert nicht Datenbankprogrammierung 5
P LDAP: Daten eintragen funktioniert nicht Datenbankprogrammierung 7
M Java Datenbankanbindung funktioniert nicht Datenbankprogrammierung 4
J Verbindung zu Derby Datenbank funktioniert nicht Datenbankprogrammierung 14
E Warum funktioniert das Erzeugen einer View nicht? Datenbankprogrammierung 1
M DB-Zugriff funktioniert nach JAR-Erstellung nicht mehr Datenbankprogrammierung 3
L SQL Statement mit Switch-Case funktioniert nicht Datenbankprogrammierung 6
L MySQL App/Java Zugriff auf Mysql-DB funktioniert nicht Datenbankprogrammierung 1
1 MySQL Verbindung mit localhost als IP funktioniert, aber mit normaler IP nicht Datenbankprogrammierung 2
J Datenbankeintag eines Warenkorbes funktioniert nicht Datenbankprogrammierung 4
P SQL-Statement "Top 1" oder "limit" funktioniert nicht Datenbankprogrammierung 12
crashfinger jdbc-connection mit jre7 funktioniert nicht Datenbankprogrammierung 5
W No data found: SQL-Abfrage funktioniert nur beim Debuggen Datenbankprogrammierung 3
X3TitanCore mysqldump funktioniert nicht Datenbankprogrammierung 8
C JDBC Datenbank funktioniert nicht Datenbankprogrammierung 7
T HQL Query funktioniert nicht? Datenbankprogrammierung 8
X Rollback mit Savepoint funktioniert auf Oracle nicht (ORA-01086) Datenbankprogrammierung 4
F wie funktioniert if Statement in SELECT? Datenbankprogrammierung 2
W HSQLDB executeUpdate funktioniert nicht Datenbankprogrammierung 20
S HSQLDB DELETE-Statement funktioniert nicht Datenbankprogrammierung 4
K MySQL Verbindung funktioniert in Netbeans aber .jar funktioniert nicht Datenbankprogrammierung 5
A Rollback funktioniert nicht Datenbankprogrammierung 10
C MySQL Update funktioniert nicht Datenbankprogrammierung 11
H SQL Abfrage funktioniert nicht. Datenbankprogrammierung 10
D Problem: Prepared Statement (Insert) funktioniert nicht. Datenbankprogrammierung 3
E Einfache Abfrage funktioniert nicht Datenbankprogrammierung 3
G MSSQL Server SELECT Abfrage funktioniert nicht Datenbankprogrammierung 4
J Insert auf Access DB funktioniert nicht Datenbankprogrammierung 5
V commit funktioniert nicht Datenbankprogrammierung 2
A Like-Anweisung funktioniert nicht korrekt Datenbankprogrammierung 2
Y ORACLE - Autoincrement funktioniert nicht Datenbankprogrammierung 2
K Zugriff mittels JDBC funktioniert nur lokal Datenbankprogrammierung 5
V MySql abfrage funktioniert auf einmal nicht mehr Datenbankprogrammierung 2
S Gleiche Verbindung funktioniert einmal und einmal nicht Datenbankprogrammierung 4
E executeUpdate() funktioniert auf einmal nicht Datenbankprogrammierung 2
B MySQL Stored Procedure Aufruf funktioniert nicht Datenbankprogrammierung 4
B Update funktioniert nicht Datenbankprogrammierung 8
A INSERT funktioniert nur im Debug-Modus Datenbankprogrammierung 19
G Insert in MS SQL Server Db funktioniert nicht richtig Datenbankprogrammierung 16
W RsultSet auf null abfragen funktioniert nicht Datenbankprogrammierung 4
D Datenbankzugriff auf MS SQL Server 2000 funktioniert nicht Datenbankprogrammierung 3
F Insert Funktioniert nicht Datenbankprogrammierung 6
S MySQL-Abfrage unter java funktioniert nicht! Datenbankprogrammierung 4
P Insert Into mit Acces und Autowert funktioniert nicht Datenbankprogrammierung 2
J DB Verbindung im IDE funktioniert, als jar nicht Datenbankprogrammierung 5
A delete aus datenbank, funktioniert nicht so richtig Datenbankprogrammierung 10
L DB-Verbindung (Oracle) funktioniert nicht Datenbankprogrammierung 35
S Statement.getGeneratedKeys() funktioniert nicht Datenbankprogrammierung 4
R Datenbank zugriff funktioniert nur offline Datenbankprogrammierung 2
G PostgreSQL Nach Monaten auf einmal ClassNotFound-Exception Datenbankprogrammierung 3
S Daten aus Form in Datenbank nur einmal eintragen Datenbankprogrammierung 2
M MySQL: Spalte auf einmal füllen, ohne iterieren zu müssen Datenbankprogrammierung 4
S Connection/Statement/ResultSet auf einmal geschlossen Datenbankprogrammierung 8
A Viele Abfragen auf einmal: Performance Datenbankprogrammierung 2
Q Resultset will in While nur EINMAL liefern! Datenbankprogrammierung 8

Ähnliche Java Themen

Neue Themen


Oben