Derby/JavaDB OpenJPA, @oneToMany und Probleme

schulhaus

Mitglied
Guten Tag zusammen 🙂

Seit einiger Zeit versuche ich eine OneToMany-Beziehung mit OpenJPA zu realisieren. Leider klappt dies nicht so wie ich mir das vorstelle. Die entsprechende Liste, welche ich von der Entität "Forrest" durch den Getter "getTrees()" erhalte, ist leider immer leer.

Für einen kleinen Tipp wäre ich sehr dankbar. Natürlich bin ich auch über sonstige Kritik sehr froh 🙂

Der abgesetzte Query stimmt meiner Meinung nach:
Code:
499  Test  TRACE  [main] openjpa.jdbc.SQL - <t 30091157, conn 31614466> executing prepstmnt 21072336 SELECT t0.id, t1.id, t1.height, t1.name FROM Forrest t0 INNER JOIN Tree t1 ON t0.id = t1.FORREST_ID ORDER BY t0.id ASC


Mein Versuchsaufbau sieht wie folgt aus:
Entität "Tree":
Java:
package test.inverseMapping.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Tree")
public class Tree {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	private String name;

	private int height;

	@ManyToOne(targetEntity = Forrest.class)
	private Forrest forrest;

	/**
	 * @return the id
	 */
	public long getId() {
		return id;
	}

	/**
	 * @param pId
	 *            the id to set
	 */
	public void setId(long pId) {
		id = pId;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param pName
	 *            the name to set
	 */
	public void setName(String pName) {
		name = pName;
	}

	/**
	 * @return the height
	 */
	public int getHeight() {
		return height;
	}

	/**
	 * @param pHeight
	 *            the height to set
	 */
	public void setHeight(int pHeight) {
		height = pHeight;
	}

	/**
	 * @return the forrest
	 */
	public Forrest getForrest() {
		return forrest;
	}

	/**
	 * @param pForrest the forrest to set
	 */
	public void setForrest(Forrest pForrest) {
		forrest = pForrest;
	}
}

Entität "Forrest":
Java:
package test.inverseMapping.entity;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "Forrest")
public class Forrest {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	private String name;

	@OneToMany(targetEntity = Tree.class, mappedBy = "forrest", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
	private List<Tree> trees;

	/**
	 * @return the id
	 */
	public long getId() {
		return id;
	}

	/**
	 * @param pId
	 *            the id to set
	 */
	public void setId(long pId) {
		id = pId;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param pName
	 *            the name to set
	 */
	public void setName(String pName) {
		name = pName;
	}

	/**
	 * @return the trees
	 */
	public List<Tree> getTrees() {
		return trees;
	}

	/**
	 * @param pTrees
	 *            the trees to set
	 */
	public void setTrees(List<Tree> pTrees) {
		trees = pTrees;
	}
}

Testfall:
Java:
package test.inverseMapping.test;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import test.inverseMapping.entity.Forrest;
import test.inverseMapping.entity.Tree;

public class OneToManyTest extends TestCase {

	private EntityManager entityManager;

	@Before
	public void setUp() throws Exception {
		EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("Test");
		entityManager = entityManagerFactory.createEntityManager();
	}

	@After
	public void tearDown() throws Exception {
		entityManager.close();
	}

	@Test
	public void testPersistenceUnit() {
		assertEquals(true, entityManager.isOpen());
	}

	@Test
	public void testInverseMapping() {
		entityManager.getTransaction().begin();

		Forrest forrest = new Forrest();

		forrest.setName("Shadow Wood");

		entityManager.persist(forrest);

		for (int i = 0; i < 10; i++) {
			Tree tree = new Tree();
			
			tree.setHeight(i * 8);
			tree.setName("tree " + i);
			tree.setForrest(forrest);
			
			entityManager.persist(tree);
		}

		entityManager.getTransaction().commit();

		Forrest answer = entityManager.createQuery("SELECT f FROM Forrest f", Forrest.class).getSingleResult();

		List<Tree> trees = answer.getTrees();
		System.out.println(trees.size());
		for (Tree tree : trees) {
			System.out.println(tree.getName());
		}
		
		Tree testTree = entityManager.createQuery("SELECT t FROM Tree t", Tree.class).getResultList().get(0);
		
		System.out.println(testTree.getForrest().getName());
	}

}

Links welche zum Problem passen:
Understanding the Java Persistence API, Part 2: Relationships the JPA way - JavaWorld
Apache OpenJPA 2.1 User's Guide
http://www.java-forum.org/datenbankprogrammierung/103316-unidirektionale-onetomany-beziehung.html
One to Many MappingJPAJava
 
Zuletzt bearbeitet:
Den Fehler habe ich soeben gefunden.

Dabei ist es wichtig, den InverseManager zu aktivieren. Dies geschieht nach Manual mit:
[XML]<property name="openjpa.InverseManager" value="true"/>[/XML]

Danach sind die Collections von einem Inversemapping abgefüllt.

Apache OpenJPA 2.1 User's Guide

Komplette Persistence.xml:
[XML]<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="Test" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>test.inverseMapping.entity.Forrest</class>
<class>test.inverseMapping.entity.Tree</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:derby:data/db;create=true" />
<property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="openjpa.ConnectionUserName" value="user" />
<property name="openjpa.ConnectionPassword" value="user" />

<property name="openjpa.InverseManager" value="true"/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='add,deleteTableContents',ForeignKeys=true)"/>
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
</properties>
</persistence-unit>
</persistence>
[/XML]
 

Neue Themen


Zurück
Oben