开发者

Hibernate Reference column in table to indicate how to unmarshall an attribute in a different column in the same table

开发者 https://www.devze.com 2022-12-19 17:49 出处:网络
I have an entity that I want to persist through Hibernate (3.2) The EntityBean has a column that indicates how another value of the entity bean should be unmarshalled:

I have an entity that I want to persist through Hibernate (3.2) The EntityBean has a column that indicates how another value of the entity bean should be unmarshalled:

<class name="ServiceAttributeValue" table="service_attribute_value">
      <cache usage="nonstrict-read-write"/>
      <id name="id" column="id" type="int-long">
         <generator class="native"/>
      </id>
      <property name="serviceAttribute" type="service-attribute" column="service_attribute" not-null="true" />
      <!-- order is important here -->
      <property name="value" type="attribute-value" not-null="true">
         <column name="service_attribute" />
         <column name="id_value"/>
         <column name="enum_value"/>
         <column name="string_value"/>
         <column name="int_value"/>
         <column name="boolean_value"/>
         <column name="double_value"/>
      </property>
   </class>

The "service_attribute" column indi开发者_运维知识库cates which of the columns for the "value" property to look at when it unmarshalls the value and, more importantly, exactly what Type the value should be, for example the class of the Enum if the enum_value is to be read, or the type of Bean if the the id_value is to be read.

The value property uses a custom CompositeUserType to do the unmarshalling and within this I wish to reference the service_attribute column (although not write to it), however when I try to do this I get the following error:

org.hibernate.MappingException: Repeated column in mapping for entity: com.precurse.apps.rank.model.service.ServiceAttributeValue column: service_attribute (should be mapped with insert="false" update="false")

However within the definition of the composite property these xml attributes are not defined (only within a normal property).

Does anyone know of a way of overcoming this, or if there is a better solution to this propblem.

If you need any more information please let me know,

Cheers Simon


I had a similar problem and changing the case of one column solved the problem. Could give a try!
e.g., one column could be service_attribute other Service_Attribute.


You can try this. Instead of mapping both values as property on the same table, map one of the property using join to itself and keep the other property as the way it is. This case you will be able to access the same property in both places. Just remember to name the property as different name.

      <join table="service_attribute_value">
         <key column = "id" />
         <property name="serviceAttribute" type="service-attribute" column="service_attribute" not-null="true"  />
      </join>

      <!-- order is important here -->
      <property name="value" type="attribute-value" not-null="true">
         <column name="service_attribute" />
         <column name="id_value"/>
         <column name="enum_value"/>
         <column name="string_value"/>
         <column name="int_value"/>
         <column name="boolean_value"/>
         <column name="double_value"/>
      </property>


based on your description, it seems like what you want to do is creating different subclasses based on the service_attribute. Instead of trying to achieve repeated column mapping which is not allow in hibernate, you can take a look hibernate inheritance mapping.


I Think I found a solution albeit not a very elegant one.

in the

 public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
         throws HibernateException, SQLException {

method of the CompositeUserType the "owner" argument passed to the method contains the id of the object who's service_attribute I want to access.

Annoyingly the actual serviceAttribute of the owner is not accessable or has not been set at this stage (I played around with the ordering of the elements in the hbm.xml config, in case this was an ordering thing, but unfortunatly still no joy), so I can't simply access it.

Anyway the id of the owner object is set, so I then used the session argument to run a HQL query based on the id to access the serviceAttribute which I then used to correctly unmarshall the value property.

The drawback of this solution is that it requires a HQL query as an overhead to the unmarshalling process, although its within the same session, its still not optimal.

If anyone has any ideas for a better solution I'd be very grateful.

Cheers

0

精彩评论

暂无评论...
验证码 换一张
取 消