We have the following problem with manually administering a relation in our domain model.
The application knows devices and users who are responsible for the devices. In fact the domain model is much more complex, but we can focus on these domain objects for now. One user is responsible for n devices, so we have an 1:n relation. A device has the attribute deviceId (a serial number of the device).
The relevant mappings look like:
Code:
public class User {
@ManyToOne
public Device getDevice() {
return device;
}
@CollectionOfElements(fetch = FetchType.EAGER)
@JoinTable(name = "USER_DEVICEID", joinColumns = @JoinColumn(name = "User_id"))
@Column(name = "deviceId")
public Set<String> getDeviceIds() {
return deviceIds;
}
}
public class Device {
private String deviceId;
}
Sometimes the application gets a request (via a Servlet) with a deviceId and has to figure out which user is responsible for the device with that deviceId. Because of some security reasons (that would be to difficult to explain here) we are not allowed to access the table Device in that situation. Therefore we cannot look it up like findDeviceByDeviceId().
We are only allowed to access the table User and the table User_DeviceId which we added to get a mapping from User to deviceId without having to use the table Device.
That works fine, but now we are responsible to maintain this "relation table" User_DeviceId whenever a device is created, updated or deleted and we are looking for the best strategy of doing that. We wrote a Hibernate Interceptor, but that doesn't seem to work, as the interceptor has to change a user object (add or remove a deviceId) whenever a device object is saved/updated/deleted.
We had implemented it like
Code:
public class MyInterceptor extends EmptyInterceptor {
@Override
public boolean onSave(final Object entity, final Serializable id, final Object[] state, final String[] propertyNames, final Type[] types) {
if (entity instanceof Device) {
return addDeviceIdToUser((Device) entity);
} else {
return super.onSave(entity, id, state, propertyNames, types);
}
}
@Override
public boolean onFlushDirty(final Object entity, final Serializable id, final Object[] currentState, final Object[] previousState, final String[] propertyNames, final Type[] types) {
...
}
@Override
public void onDelete(final Object entity, final Serializable id, final Object[] state, final String[] propertyNames, final Type[] types) {
...
}
private boolean addDeviceIdToUser(final Device device) {
final User user = device.getDeviceType().getMandator().getUser();
user.addDeviceId(device.getDeviceId());
return false;
}
but that cannot work correctly. I think you should not use hibernate interceptors to change another object than "entity" and you are only allowed to make your changes to the "state" object array, aren't you?
Does anybody knows a better strategy to manually maintaining the relation from User to DeviceId when a Device is changed? Any hints would be greatly appreciated.
Thanks in advance,
Ole