views:

213

answers:

3
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;
<hibernate-mapping package="org.lexiclan.orm.dao">
    <class name="Address" table="ADDRESSES" lazy="false">
     <id name="addressId" column="ADDRESS_ID">
      <generator class="native" />
     </id>
     <many-to-one name="addressType" column="ADDRESS_TYPE_ID" not-null="true" class="AddressType" lazy="false" />
     <many-to-one name="contact" column="CONTACT_ID" not-null="true" class="Contact" lazy="false" />
     <property name="address1" column="ADDRESS_1" />
     <property name="address2" column="ADDRESS_2" />
     <property name="city" column="CITY" />
     <property name="stateProvince" column="STATE_PROVINCE" />
     <property name="zipPostalCode" column="ZIP_POSTAL_CODE" />
     <property name="countryRegion" column="COUNTRY_REGION" />
    </class>
</hibernate-mapping>

In this example, an address requires both a contact and an address type relationship before you can use "Session.save()" (which is what I want), but when I want to use "Session.delete()" I have to also specify a contact and address type relationship because of the not-null. Is there a way to require those values on save, but not on update/delete operations?

A: 

I did not found any way to do it. Consider using another ORM.

The question is referencing Hibernate, but this problem is not strictly Hibernate problem, and as such changing the ORM would not help.
Zoran Regvart
It doesn't matter. Anyway changing ORM would be a good idea.
A: 

I think that not null is a database constraint. Why don't you use a HQL statement like the one below:

session.Delete("from Order o where o.Id = :Id", id, NHibernate.NHibernateUtil.Int32);

That way you don't need the whole object to delete it from database.

nandokakimoto
+4  A: 

"not-null" is not a conditional constraint. Either your properties (addressType / contact) are ALWAYS required, in which case you specify them as not-null="true" or they are not.

"Sometimes" is the same as "not required". If you need to perform conditional validation (for example, during insert but not during update or based on some other entity state), you can either do so in your code prior to invoking session methods or you can write an event listener or an interceptor to do it for you.

That said, deletion is a special case. session.delete() deletes persisted entity, which means it has already been validated and has its properties as not-null. If you want to delete by id (that is, you don't have the entity loaded in session), you can use session.load() to obtain its proxy:

Address toBeDeleted = (Address) session.load(Address.class, id);
session.delete(toBeDeleted);

Either way I'm not quite sure what you mean by "I have to also specify a contact and address type relationship because of the not-null" in case of deletion. You don't - they're already set; they were specified when entity was persisted.

ChssPly76
When I said "I have to" I just meant that Hibernate requires that those members on the object be set when I call save() because the object hasn't been loaded yet.
hal10001
Are you talking about **deletion**? If so, you don't ever have to call `save()` - either you call `get()` / `delete()` or `load()` / `delete()`. Otherwise, (if you're not talking about deletion) I've addressed conditional state checks in my answer above.
ChssPly76