Hibernate - Probleme save eines Objekts mit Abhängigkeiten

y0dA

Erfahrenes Mitglied
Ich kann ich folgende Sachlage (Receiver) verbessern?
Code:
public void storeTrack(final Track track) {
		Session session = HibernateUtil.getCurrentSession();
		TrackDAO trackDAO = new TrackDAO();
		TrackPointDAO trackPointDAO = new TrackPointDAO();
		ReceiverDAO receiverDAO = new ReceiverDAO();
		try {	
			session.beginTransaction();
			trackDAO.setSession(session);
			trackPointDAO.setSession(session);
			receiverDAO.setSession(session);
			if (!session.contains(track.getReceiver())) {
				Receiver receiver = receiverDAO.getReceiver(track.getReceiver().getId());
				if (receiver != null) {
					receiver = receiverDAO.makePersistent(receiver);
					track.setReceiver(receiver);
				} else {
					//FIXME welche Exception werfen!!
					throw new RuntimeException ("receiver which global id: " + receiver.getGlobalID()
							+ "doesnt exist");
				}
			}
			/* save or update track */
			trackDAO.makePersistent(track);
			for (TrackPoint point : track.getTrackPointList()) {
				point.setTrack(track);
				/* save or update track point */
				trackPointDAO.makePersistent(point);	
			}
			session.getTransaction().commit();	
		} catch (Exception e) {
			e.printStackTrace();
			if (session.getTransaction() != null) {
				session.getTransaction().rollback();
				TrackControllerModel.LOGGER.fatal(
						"class: TrackControllerModel method: storeTrack, exception occurred while"
						+ " store tracks: ", e);
			}
		} finally {
			session = null;
			trackDAO = null;
			trackPointDAO = null;
			receiverDAO = null;
		}
	}
Sprich wenn Track zu diesem Zeitpunkt einen Receiver beinhaltet der der Session nicht bekannt ist bekomme ich eine Exception, wenn ich den Receiver der Session nicht bekannt gebe. Gibt es hierfür eine bessere Lösung oder muss ich ein "saveOrUpdate" durchführen, obwohl ich eigentlich das Receiver Objekt nicht updaten möchte?


Weitere Frage betreffend Reihenfolge:

Also folgende 3 Tabellen: Receiver --> Track (FK von Receiver) --> TrackPoint (FK von Track)
Muss ich hierbei zunächst TrackPoint dann Track und zuletzt Receiver inserten?

Denn wenn ich es so mache, bekomme ich folgende Exception:
Code:
Caused by: java.sql.BatchUpdateException: ORA-02291: Integritäts-Constraint (NAVTEQ.FK_TP_T_ID) verletzt - übergeordneter Schlüssel nicht gefunden
NAVTEQ.FK_TP_T_ID = in der Tabelle TrackPoint der FK zu Track

mfg
 
Guten Morgen -.- !
Also mein Problem besteht darin, dass hier:
Code:
session.getTransaction().commit();
Erst der Track persistiert wird, sprich er existiert noch nicht in der DB und deshalb bekomme ich die Exception, weil TrackPoint ja auf diesen Track zeigt.

+)Wie kann ich dieses Problem umgehen?

+)Warum schreibt Hibernate nicht einfach Track in die DB und dann versucht es erst TrackPoint in die DB zu schreiben?

+)Muss ich nun wirklich das Problem wie folgt lösen:
Code:
public void storeTrack(final Track track) {
		Session session = HibernateUtil.getCurrentSession();
		TrackDAO trackDAO = new TrackDAO();
		TrackPointDAO trackPointDAO = new TrackPointDAO();
		ReceiverDAO receiverDAO = new ReceiverDAO();
		try {	
			session.beginTransaction();
			trackDAO.setSession(session);
//			trackPointDAO.setSession(session);
			receiverDAO.setSession(session);
			if (!session.contains(track.getReceiver())) {
				Receiver receiver = receiverDAO.getReceiver(track.getReceiver().getId());
				if (receiver != null) {
					receiver = receiverDAO.makePersistent(receiver);
					track.setReceiver(receiver);
				} else {
					//FIXME welche Exception werfen!!
					throw new RuntimeException ("receiver which global id: " + receiver.getGlobalID()
							+ "doesnt exist");
				}
			}
			
			/* save or update track */
			trackDAO.makePersistent(track);
			session.getTransaction().commit();
			session = HibernateUtil.getCurrentSession();
			session.beginTransaction();
			trackPointDAO.setSession(session);
			for (TrackPoint point : track.getTrackPointList()) {
				point.setTrack(track);
				/* save or update track point */
				trackPointDAO.makePersistent(point);	
				break;
			}
			session.getTransaction().commit();	
		} catch (Exception e) {
			e.printStackTrace();
			if (session.getTransaction() != null) {
				session.getTransaction().rollback();
				TrackControllerModel.LOGGER.fatal(
						"class: TrackControllerModel method: storeTrack, exception occurred while"
						+ " store tracks: ", e);
			}
		} finally {
			session = null;
			trackDAO = null;
			trackPointDAO = null;
			receiverDAO = null;
		}
	}

Ich bitte um Rat.
 
Hast du beim Mapping die Relation fürs Kaskadieren markiert?

REINHAUN!

Aloha mein Freund und Helfer :)

Nein hab ich nicht, höre ich auch zum ersten mal - werd mir diesbezüglich wohl mal die Hibernate Doku ansehen.

Also kann ich alles auf einmal inserten?

**EDIT**
Ich danke für den Hinweis!
Mit folgendem funktioniert es nun tadellos:
Code:
cascade="save-update"
 
Zuletzt bearbeitet:
Mit Hibernate als JPA Provider und Spring für das Transaktionsmanagement reduziert sich der Code da oben auf
Java:
em.persist(track)
und ein @Transactional an der Methodedes Clients.

;)

REINHAUN!
 
Zurück