Java tutorial
/** * This code is part of the Harmony System implemented in Work Package 1 * of the Phosphorus project. This work is supported by the European * Comission under the Sixth Framework Programme with contract number * IST-034115. * * Copyright (C) 2006-2009 Phosphorus WP1 partners. Phosphorus Consortium. * http://ist-phosphorus.eu/ * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package eu.ist_phosphorus.harmony.idb.database.hibernate; import java.net.URI; import java.net.URISyntaxException; import java.util.Date; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.persistence.Basic; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.MapKey; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.annotations.Proxy; import org.hibernate.criterion.Restrictions; import eu.ist_phosphorus.harmony.common.serviceinterface.databinding.jaxb.DomainInformationType; import eu.ist_phosphorus.harmony.common.serviceinterface.databinding.jaxb.DomainRelationshipType; import eu.ist_phosphorus.harmony.common.serviceinterface.databinding.jaxb.DomainTechnologyType; import eu.ist_phosphorus.harmony.common.utils.Helpers; import eu.ist_phosphorus.harmony.idb.database.TransactionManager; import eu.ist_phosphorus.harmony.idb.database.TransactionManagerLoad; import eu.ist_phosphorus.harmony.idb.exceptions.database.DatabaseException; /** * Java representation of of the database entity {@link Domain}. This object * does not contain any logic. * * @author Stephan Wagner (wagners@cs.uni-bonn.de) * @version 0.1 */ @Entity @Table(name = "Domain") @Proxy(lazy = false) public class Domain implements java.io.Serializable, Comparable<Domain> { // Fields /** */ private static final long serialVersionUID = 8895516446253440666L; /** Name of the domain (primary key of the table in the Database). */ private String name; private int seqNo; /** Description of the domain. */ private String description; /** URI of the reservationEPR. */ private String reservationEPR; private Date registered = new Date(); private URI reservationURI = null; /** URI of the topologyEPR. */ private String topologyEPR; /** URI of the notificationEPR. */ private String notificationEPR; private String relationship; private int avgDelay; private int maxBW; private boolean disabled; private int priority; private Set<DomSupportedAdaption> supportedAdaptions = new HashSet<DomSupportedAdaption>(0); private Set<DomSupportedSwitch> supportedSwitchMatrix = new HashSet<DomSupportedSwitch>(0); private Set<DomSupportedBandwidth> supportedBandwidths = new HashSet<DomSupportedBandwidth>(0); /** Set of prefixes */ private Set<TNAPrefix> prefixes = new HashSet<TNAPrefix>(0); /** Set of endpoints */ private Set<Endpoint> endpoints = new HashSet<Endpoint>(0); /** Set of nrpsConnections */ private Set<NrpsConnections> nrpsConnections = new HashSet<NrpsConnections>(0); public Date getRegistered() { return this.registered; } public void setRegistered(final Date registered) { this.registered = registered; } @Basic(optional = true) public int getSeqNo() { return this.seqNo; } public void setSeqNo(final int seqNo) { this.seqNo = seqNo; } @Basic(optional = true) public String getRelationship() { return this.relationship; } public void setRelationship(final String relationship) { this.relationship = relationship; } @Basic(optional = true) public int getAvgDelay() { return this.avgDelay; } public void setAvgDelay(final int avgDelay) { this.avgDelay = avgDelay; } @Basic(optional = true) public int getMaxBW() { return this.maxBW; } public void setMaxBW(final int maxBW) { this.maxBW = maxBW; } /** * @return the disabled */ public int getDisabled() { if (this.disabled) { return 1; } else { return 0; } } /** * @param disabled * the disabled to set */ public void setDisabled(int disabled) { if (disabled == 0) { this.disabled = false; } else { this.disabled = true; } } /** * @return the priority */ public int getPriority() { return this.priority; } /** * @param priority * the priority to set */ public void setPriority(int priority) { this.priority = priority; } /** * @return the supported technology adaption */ @OneToMany(mappedBy = "domain", fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL }) @MapKey(name = "PK_Adaption") public Set<DomSupportedAdaption> getSupportedAdaptions() { return this.supportedAdaptions; } /** * the technology adaption to set * @param adaption */ public void setSupportedAdaptions(final Set<DomSupportedAdaption> adaption) { this.supportedAdaptions = adaption; } public final boolean addAdaption(final DomSupportedAdaption adaption) { adaption.setDomain(this); return this.getSupportedAdaptions().add(adaption); } public final boolean addAdaption(final String adaption) { return this.getSupportedAdaptions().add(new DomSupportedAdaption(this, adaption)); } /** * @return the supported technology switch matrix */ @OneToMany(mappedBy = "domain", fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL }) @MapKey(name = "PK_Switch") public Set<DomSupportedSwitch> getSupportedSwitchMatrix() { return this.supportedSwitchMatrix; } /** * the technology switch matrix to set * @param switchMatrix */ public void setSupportedSwitchMatrix(final Set<DomSupportedSwitch> switchMatrix) { this.supportedSwitchMatrix = switchMatrix; } public final boolean addSwitch(final DomSupportedSwitch switchParam) { switchParam.setDomain(this); return this.getSupportedSwitchMatrix().add(switchParam); } public final boolean addSwitch(final String switchParam) { return this.getSupportedSwitchMatrix().add(new DomSupportedSwitch(this, switchParam)); } /** * @return the supported bandwidth */ @OneToMany(mappedBy = "domain", fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL }) @MapKey(name = "PK_Bandwidth") public Set<DomSupportedBandwidth> getSupportedBandwidths() { return this.supportedBandwidths; } /** * the supported bandwidth to set * @param bandwidth */ public void setSupportedBandwidths(final Set<DomSupportedBandwidth> bw) { this.supportedBandwidths = bw; } public final boolean addBandwidth(final DomSupportedBandwidth bw) { bw.setDomain(this); return this.getSupportedBandwidths().add(bw); } public final boolean addBandwidth(final long bw) { return this.getSupportedBandwidths().add(new DomSupportedBandwidth(this, bw)); } // Constructors /** default constructor. */ private Domain() { // Nothing to do here... } /** * minimal Constructor. * * @param nameParam * Id of the Domain in the database * @param reservationEPRParam * URI of the reservationEPR * @param topologyEPRParam * URI of the topologyEPR * @throws URISyntaxException */ public Domain(final String nameParam, final String reservationEPRParam, final String topologyEPRParam) { this.name = nameParam; this.description = null; this.setReservationEPR(reservationEPRParam); this.topologyEPR = topologyEPRParam; } /** * full constructor. * * @param nameParam * name of the Domain * @param descriptionParam * description of the Domain * @param reservationEPRParam * URI of the reservationEPR * @param topologyEPRParam * URI of the topologyEPR * @throws URISyntaxException */ public Domain(final String nameParam, final String descriptionParam, final String reservationEPRParam, final String topologyEPRParam, final String notificationEPRParam) { this.name = nameParam; this.description = descriptionParam; this.setReservationEPR(reservationEPRParam); this.topologyEPR = topologyEPRParam; this.notificationEPR = notificationEPRParam; } // Property accessors /** * @return name */ @Id public final String getName() { return this.name; } /** * @param nameParam * name of the Domain */ public final void setName(final String nameParam) { this.name = nameParam; } /** * @return description of the Domain */ @Basic(optional = true) public final String getDescription() { if (null == this.description) { this.description = ""; } return this.description; } /** * @param descriptionParam * description of the domain */ public final void setDescription(final String descriptionParam) { this.description = descriptionParam; } /** * @return the reservationEPR URI */ public final String getReservationEPR() { if (null == this.reservationEPR) { this.reservationEPR = ""; } return this.reservationEPR; } /** * @param reservationEPRParam * URI of the reservationEPR * @throws URISyntaxException */ public final void setReservationEPR(final String reservationEPRParam) { try { this.reservationURI = new URI(reservationEPRParam); } catch (final URISyntaxException e) { e.printStackTrace(); } this.reservationEPR = reservationEPRParam; } @Transient public final URI getReservationURI() { return this.reservationURI; } /** * Christian: This method now may return null. I might have to fight about * this with Alex, but if this function return an empty string instead of * null, then the empty string is also written to the database; and I am not * sure if an empty string is a valid URI (which is what this field should * be)! * * @return the topologyEPR URI */ @Basic(optional = true) public final String getTopologyEPR() { return this.topologyEPR; } /** * @param topologyEPRParam * URI of the topologyEPR */ public final void setTopologyEPR(final String topologyEPRParam) { this.topologyEPR = topologyEPRParam; } /** * @return the notificationEPR */ @Basic(optional = true) public String getNotificationEPR() { return this.notificationEPR; } /** * @param notificationEPR * the notificationEPR to set */ public void setNotificationEPR(final String notificationEPR) { this.notificationEPR = notificationEPR; } /** * @return the prefixes */ @OneToMany(mappedBy = "domain", fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.ALL }) @MapKey(name = "prefix") public final Set<TNAPrefix> getPrefixes() { return this.prefixes; } /** * @param prefixes * the prefixes to set */ public final void setPrefixes(final Set<TNAPrefix> prefixes) { this.prefixes = prefixes; // TODO: maybe set the domainName here } public final boolean addPrefix(final TNAPrefix prefix) { prefix.setDomain(this); return this.getPrefixes().add(prefix); } public final boolean addPrefix(final String prefix) { return this.getPrefixes().add(new TNAPrefix(this, prefix)); } /** * @return the endpoints */ @OneToMany(mappedBy = "domain", fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.REMOVE }) @MapKey(name = "TNA") public Set<Endpoint> getEndpoints() { return this.endpoints; } /** * @param endpoints * the endpoints to set */ public void setEndpoints(final Set<Endpoint> endpoints) { this.endpoints = endpoints; } public final boolean addEndpoint(final Endpoint end) { end.setDomain(this); return this.getEndpoints().add(end); } /** * @return the nrpsConnections */ @OneToMany(mappedBy = "domain", fetch = FetchType.LAZY, cascade = { javax.persistence.CascadeType.REMOVE }) @MapKey(name = "pkNrpsConnection") public Set<NrpsConnections> getNrpsConnections() { return this.nrpsConnections; } /** * @param nrpsConnections * the nrpsConnections to set */ public void setNrpsConnections(final Set<NrpsConnections> nrpsConnections) { this.nrpsConnections = nrpsConnections; } public final boolean addNrpsConnection(final NrpsConnections conn) { conn.setDomain(this); return this.getNrpsConnections().add(conn); } /** * @param domainParam * domain to be checked * @return true if equals */ @Override public final boolean equals(final Object o) { if (o.getClass().equals(Domain.class)) { return this.isEqual((Domain) o); } return false; } /** * @param o * @return */ public final boolean isEqual(final Domain domainParam) { if (this.hashCode() == domainParam.hashCode()) { return true; } return false; } /** * */ @Override public final int hashCode() { int result = this.getName().hashCode() ^ new Long(Helpers.trimDateToSeconds(this.getRegistered())).hashCode() ^ ((this.getReservationEPR() == null) ? 0 : this.getReservationEPR().hashCode()) ^ ((this.getTopologyEPR() == null) ? 0 : this.getTopologyEPR().hashCode()) ^ ((this.getNotificationEPR() == null) ? 0 : this.getNotificationEPR().hashCode()) ^ ((this.getDescription() == null) ? 0 : this.getDescription().hashCode()) ^ ((this.getRelationship() == null) ? 0 : this.getRelationship().hashCode()) ^ this.getSeqNo() ^ this.getAvgDelay() ^ this.getMaxBW() ^ this.getPriority() ^ this.getDisabled(); // in the underlying objects, don't use the hashCode()-method, because this can end in // dependency-circles. Instead only use the DB-primary key for the hash. // for (NrpsConnections c : this.getNrpsConnections()) { // result ^= new Long(c.getPkNrpsConnection()).hashCode(); // } // // for(Endpoint e : this.getEndpoints()) { // result ^= e.getTNA().hashCode(); // } // // for(TNAPrefix p : this.getPrefixes()) { // result ^= p.getPrefix().hashCode(); // } return result; } /** * @return copy of Domain */ @Transient public final Domain getCopy() { final Domain newDomain = new Domain(); newDomain.name = this.name; newDomain.seqNo = this.seqNo; newDomain.description = this.description; newDomain.registered = this.registered; newDomain.reservationEPR = this.reservationEPR; newDomain.reservationURI = this.reservationURI; newDomain.topologyEPR = this.topologyEPR; newDomain.notificationEPR = this.notificationEPR; newDomain.relationship = this.relationship; newDomain.avgDelay = this.avgDelay; newDomain.maxBW = this.maxBW; for (final Endpoint e : this.getEndpoints()) { newDomain.getEndpoints().add(e.getCopy(this)); } for (final TNAPrefix p : this.getPrefixes()) { newDomain.getPrefixes().add(p.getCopy()); } for (final NrpsConnections s : this.getNrpsConnections()) { newDomain.getNrpsConnections().add(s.getCopy()); } for (final DomSupportedAdaption a : this.getSupportedAdaptions()) { newDomain.getSupportedAdaptions().add(a); } for (final DomSupportedSwitch s : this.getSupportedSwitchMatrix()) { newDomain.getSupportedSwitchMatrix().add(s); } for (final DomSupportedBandwidth b : this.getSupportedBandwidths()) { newDomain.getSupportedBandwidths().add(b); } return newDomain; } public static Domain fromJaxb(final DomainInformationType jaxb) { final Domain result = new Domain(jaxb.getDomainId(), jaxb.getDescription(), jaxb.getReservationEPR(), jaxb.getTopologyEPR(), jaxb.getNotificationEPR()); if (jaxb.isSetSequenceNumber()) { result.setSeqNo(jaxb.getSequenceNumber().intValue()); } if (jaxb.isSetRelationship()) { result.setRelationship(jaxb.getRelationship().value()); } if (jaxb.isSetAvgDelay()) { result.setAvgDelay(jaxb.getAvgDelay().intValue()); } if (jaxb.isSetMaxBW()) { result.setMaxBW(jaxb.getMaxBW().intValue()); } for (final String prefix : jaxb.getTNAPrefix()) { result.addPrefix(prefix); } if (jaxb.isSetTechnology()) { DomainTechnologyType dtt = jaxb.getTechnology(); for (String s : dtt.getDomainSupportedAdaptation()) { result.addAdaption(s); } for (String s : dtt.getDomainSupportedSwitchMatrix()) { result.addSwitch(s); } for (long b : dtt.getDomainSupportedBandwidth()) { result.addBandwidth(b); } } return result; } public void mergeFromJaxb(final DomainInformationType jaxb) { this.setName(jaxb.getDomainId()); if (jaxb.getDescription() != null) this.setDescription(jaxb.getDescription()); this.setReservationEPR(jaxb.getReservationEPR()); if (jaxb.getTopologyEPR() != null) this.setTopologyEPR(jaxb.getTopologyEPR()); if (jaxb.getNotificationEPR() != null) this.setNotificationEPR(jaxb.getNotificationEPR()); if (jaxb.getSequenceNumber() != null) this.setSeqNo(jaxb.getSequenceNumber()); if (jaxb.getRelationship() != null) this.setRelationship(jaxb.getRelationship().value()); if (jaxb.getAvgDelay() != null) this.setAvgDelay(jaxb.getAvgDelay()); if (jaxb.getMaxBW() != null) this.setMaxBW(jaxb.getMaxBW()); for (String prefix : jaxb.getTNAPrefix()) { this.addPrefix(prefix); } if (jaxb.getTechnology() != null) { DomainTechnologyType dtt = jaxb.getTechnology(); for (String s : dtt.getDomainSupportedAdaptation()) { this.addAdaption(s); } for (String s : dtt.getDomainSupportedSwitchMatrix()) { this.addSwitch(s); } for (long b : dtt.getDomainSupportedBandwidth()) { this.addBandwidth(b); } } } public DomainInformationType toJaxb() { final DomainInformationType result = new DomainInformationType(); result.setDomainId(this.getName()); if (this.getSeqNo() > 0) { result.setSequenceNumber(new Integer(this.getSeqNo())); } result.setDescription(this.getDescription()); result.setReservationEPR(this.getReservationEPR()); result.setTopologyEPR(this.getTopologyEPR()); result.setNotificationEPR(this.getNotificationEPR()); if (this.getRelationship() != null) { result.setRelationship(DomainRelationshipType.fromValue(this.getRelationship())); } if (this.getAvgDelay() > 0) { result.setAvgDelay(new Integer(this.getAvgDelay())); } if (this.getMaxBW() > 0) { result.setMaxBW(new Integer(this.getMaxBW())); } for (final TNAPrefix p : this.getPrefixes()) { result.getTNAPrefix().add(p.getPrefix()); } Set<DomSupportedAdaption> adaptions = this.getSupportedAdaptions(); Set<DomSupportedSwitch> matrix = this.getSupportedSwitchMatrix(); Set<DomSupportedBandwidth> bws = this.getSupportedBandwidths(); if (!adaptions.isEmpty() || !matrix.isEmpty() || !bws.isEmpty()) { DomainTechnologyType dtt = new DomainTechnologyType(); dtt.getDomainSupportedAdaptation(); for (final DomSupportedAdaption a : this.getSupportedAdaptions()) { dtt.getDomainSupportedAdaptation().add(a.getAdaption()); } dtt.getDomainSupportedSwitchMatrix(); for (final DomSupportedSwitch s : this.getSupportedSwitchMatrix()) { dtt.getDomainSupportedSwitchMatrix().add(s.getSwitch()); } dtt.getDomainSupportedBandwidth(); for (final DomSupportedBandwidth b : this.getSupportedBandwidths()) { dtt.getDomainSupportedBandwidth().add(b.getBandwidth()); } result.setTechnology(dtt); } return result; } /** * @param domain * Domain to be compared to * @return -1 0 or 1 * @see java.lang.Comparable#compareTo(java.lang.Object) */ public final int compareTo(final Domain domain) { if (this.name.length() < domain.getName().length()) { return -1; } else if (this.name.length() == domain.getName().length()) { return 0; } else { return 1; } } @Override public final String toString() { String result = "<domain><name>" + this.getName() + "</name>" + "<seqno>" + this.getSeqNo() + "</seqno>" + "<description>" + this.getDescription() + "</description>" + "<registered>" + this.getRegistered() + "</registered>" + "<reservationEPR>" + this.getReservationEPR() + "</reservationEPR>" + "<topologyEPR>" + this.getTopologyEPR() + "</topologyEPR>" + "<notificationEPR>" + this.getNotificationEPR() + "</notificationEPR>" + "<relationship>" + this.getRelationship() + "</relationship>" + "<avgDelay>" + this.getAvgDelay() + "</avgDelay>" + "<maxBW>" + this.getMaxBW() + "</maxBW>"; for (final DomSupportedAdaption a : this.getSupportedAdaptions()) { result += a.toString(); } for (final DomSupportedSwitch s : this.getSupportedSwitchMatrix()) { result += s.toString(); } for (final DomSupportedBandwidth b : this.getSupportedBandwidths()) { result += b.toString(); } for (final TNAPrefix p : this.getPrefixes()) { result += p.toString(); } for (final Endpoint e : this.getEndpoints()) { result += e.toString(); } for (final NrpsConnections con : this.getNrpsConnections()) { result += con.toString(); } return result + "</domain>"; } /** * Load domain from the DB. This function does not load the endpoints and * TNA prefixes the belong to the domain - there are additional methods for * doing this! * * @param domainName * ID of domain to be retrieved from the database. * @return {@link Domain} for given ID, or null if domain was not found. * @throws DatabaseException */ public static final Domain load(final String domainName) throws DatabaseException { return (Domain) (new TransactionManagerLoad(Domain.class, domainName)).getResult(); } /** * Locate a TNA address, i.e. match the given address against prefixes of * domains in the database. * * @param tna * TNA of endpoint to locate. * @return Domain where the endpoint is located. * @throws DatabaseException * @throws HibernateException */ @Transient @SuppressWarnings("unchecked") public static final Domain getDomainMatchingTNA(final String tna) throws HibernateException, DatabaseException { return (Domain) (new TransactionManager(tna) { @Override protected void dbOperation() { final List<TNAPrefix> tmpPrefix = this.session.createCriteria(TNAPrefix.class) .setFetchMode("TNAPrefix", FetchMode.SELECT).list(); TNAPrefix match = null; for (final TNAPrefix prefix : tmpPrefix) { if (prefix.matchesPrefix((String) this.arg)) { match = prefix; // TODO longest prefix match } } if (match != null) { this.result = this.session.get(Domain.class, match.getDomain().getName()); } } }).getResult(); } @SuppressWarnings("unchecked") public static final Set<Domain> loadAll() throws DatabaseException { return (Set<Domain>) (new TransactionManager() { @Override protected void dbOperation() { final Set<Domain> result = new HashSet<Domain>(); final List<Domain> tmpDomain = this.session.createCriteria(Domain.class) .setFetchMode("Domain", FetchMode.SELECT).list(); for (final Domain d : tmpDomain) { result.add(d); } this.result = result; } }).getResult(); } @SuppressWarnings("unchecked") public final Set<VIEW_InterDomainLink> loadAllLinks() throws DatabaseException { return (Set<VIEW_InterDomainLink>) (new TransactionManager() { @Override protected void dbOperation() { final Set<VIEW_InterDomainLink> result = new HashSet<VIEW_InterDomainLink>(); for (final Endpoint e : Domain.this.getEndpoints()) { final List<VIEW_InterDomainLink> tmpSrc = this.session .createCriteria(VIEW_InterDomainLink.class).setFetchMode("", FetchMode.SELECT) .add(Restrictions.like("sourceEndpoint", e)).list(); final List<VIEW_InterDomainLink> tmpDst = this.session .createCriteria(VIEW_InterDomainLink.class).setFetchMode("", FetchMode.SELECT) .add(Restrictions.like("destEndpoint", e)).list(); for (final VIEW_InterDomainLink l : tmpSrc) { result.add(l); } for (final VIEW_InterDomainLink l : tmpDst) { result.add(l); } } this.result = result; } }).getResult(); } public final void save(final Session session) { session.saveOrUpdate(this); } public final void save() throws DatabaseException { new TransactionManager() { @Override protected void dbOperation() { save(this.session); } }; } @Transient @SuppressWarnings("unchecked") public final Set<Reservation> getAllReservations() throws DatabaseException { return (Set<Reservation>) (new TransactionManager(this) { @Override protected void dbOperation() throws Exception { final Domain me = (Domain) this.arg; final List<NrpsConnections> cList = this.session.createCriteria(NrpsConnections.class) .setFetchMode("", FetchMode.SELECT).add(Restrictions.like("domain", me)).list(); final Set<Connections> connections = new HashSet<Connections>(); for (final NrpsConnections nConn : cList) { connections.add(nConn.getConnection()); } // get services for every connection final Set<Service> services = new HashSet<Service>(); for (final Connections c : connections) { services.add(c.getService()); } // get reservations for every Service final Set<Reservation> reservations = new HashSet<Reservation>(); for (final Service s : services) { reservations.add(s.getReservation()); } this.result = reservations; } }).getResult(); } public final void delete(final Session session) { session.delete(this); } public final void delete() throws DatabaseException { /* * If a domain is deleted, it is useful to delete all topology * and reservation components related with this domain. * Endpoints, Links and Connections are automatically deleted by * foreign-key-relation in the DB. Since the relations between * reservations and services and a domain are not represented in * the DB-schema we have to do this manually. Therefore... */ List<VIEW_DomainReservationMapping> mappings = VIEW_DomainReservationMapping .getMappingsForDomain(this.getName()); for (VIEW_DomainReservationMapping mapping : mappings) { Reservation.load(mapping.getReservationId()).delete(); } new TransactionManager(this) { @Override protected void dbOperation() throws Exception { // delete the domain itself delete(this.session); } }; } }