@Override
	public synchronized Fingerprint add(Fingerprint fprint) {
		Connection conn = db.getConnection();
		Vector<PreparedStatement> vps = new Vector<PreparedStatement>();
		ResultSet rs = null;
		
		try {

			conn.setAutoCommit(false);
			Measurement m = (Measurement)fprint.getMeasurement();
			int measurementId = HomeFactory.getMeasurementHome().executeInsertUpdate(vps, m);
			m.setId(measurementId);
			// wifi
			HomeFactory.getWiFiReadingVectorHome().executeUpdate(vps, m.getWiFiReadings(), measurementId);
			// gsm
			HomeFactory.getGSMReadingVectorHome().executeUpdate(vps, m.getGsmReadings(), measurementId);			
			// bluetooth
			HomeFactory.getBluetoothReadingVectorHome().executeUpdate(vps, m.getBluetoothReadings(), measurementId);
			
			Location l = (Location)fprint.getLocation();
			int locationId = l.getId() == null ? -1 : l.getId().intValue();
			if (locationId == -1) {
				locationId = HomeFactory.getLocationHome().executeInsertUpdate(vps, l); //.getPrimaryKeyId();
				l.setId(locationId);
			}
			
			int fingerprintId = executeInsertUpdate(vps, fprint);
			conn.commit();
			
			return getById(fingerprintId);
		
		} catch (SQLException e) {
			log.log(Level.SEVERE, "add fingerprint failed: " + e.getMessage(), e);
		} finally {
			try {
				conn.setAutoCommit(true);
				if (rs != null) rs.close();
				for(PreparedStatement p : vps) {
					if (p != null) p.close();
				}
			} catch (SQLException es) {
				log.log(Level.WARNING, "failed to close statement: " + es.getMessage(), es);
			}
		}
		return null;
	}