JPA - @OneToMany Liste Probleme mit Identity Keys

y0dA

Erfahrenes Mitglied
Hi!
Folgendes Szenario:
Ich habe eine bidirektionale Beziehung zwischen Klasse Dokument und Klasse Status:
Java:
public class Ueberklasse{
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Integer id;
}

public class Dokument extends Ueberklasse{
	@OneToMany(mappedBy = "dokument", cascade = { CascadeType.MERGE,
			CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.EAGER)
	private List<Status> statusListe;
..
}

public class Status {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@ManyToOne(cascade = CascadeType.REFRESH)
	@JoinColumn(name = "dokument")
	private Dokument dokument;
..
}

Wenn ich nun in meiner Applikation ein neues Objekt vom Typ "Dokument" anlege dann hat der bspw. den Status "beantragt" und sonst keinen weiteren Status, sprich in der Liste ist genau 1 Eintrag. Das ganze wird dann über folgende Methode persistiert:
Java:
..
	@PersistenceContext(unitName = "asdf")
	private EntityManager em;
..

	@Override
	public T create(T entity) throws EntityExistsException,
			IllegalStateException, IllegalArgumentException,
			TransactionRequiredException {
		if (logger.isTraceEnabled()) {
			logger.trace("CRUDEntityFacade.create("
					+ entityClass.getSimpleName() + ")");
		}
		em.persist(entity);

		return entity;
	}
Hierbei werden alle Objekte korrekt gespeichert und nachdem "flush()" welches nachdem create aufgerufen wird sind auch alle Primärschlüssel in den Objekten gesetzt (sprich entity hat die ID gesetzt was vor dem flush() nicht so ist).

Im Folgenden kann es nun vorkommen dass sich der Status "ändert", hierbei wird nicht das aktuelle Status Objekt aktualisiert sondern ein neues Objekt mit dem neuen Status angelegt und in die "Liste statusListe" hinzugefügt (sprich es gibt dann 2 Einträge, den Ursprungsstatus und den neuen - noch nicht persistierten- Status). Hierbei wird nun folgende Methode aufgerufen:
Java:
	@Override
	public T update(T entity) throws IllegalStateException,
			IllegalArgumentException, TransactionRequiredException {
		if (logger.isTraceEnabled()) {
			logger.trace("CRUDEntityFacade.update("
					+ entityClass.getSimpleName() + ")");
		}
		em.merge(entity);

		if (logger.isDebugEnabled()) {
			logger
					.debug("CRUDEntityFacade.update(Serializable) updated 1 entity: "
							+ entity.toString());
		}
		return entity;
	}

Das Ergebnis davon ist nun dass der neue Status zwar persistiert wird jedoch die ID nicht gesetzt wird. Auch flush() bringt hier keine Abhilfe.

Ist natürlich unschön dass die ID nicht gesetzt wird und die Objekte neuladen nach dem speichern sollte eigentlich auch nicht der richtige Weg sein, zumal es beim speichern ja klappt - nur das merge macht Probleme.
 

Neue Beiträge

Zurück