I have a user type that maps 5 fields on an Address file (addressLine1, addressLine2, addressLine3 etc) to a list, so that my object can have a collection of address lines rather than the database representation.
I'm trying to do an address search using HQL, that is searching on addressLine1 only. The HQL (with no where clause appended is as follows:
SELECT new net.targetgroup.broker.application.ApplicationSearchResult(application.identifier, applicant.lastName, applicant.firstName, applicant.birthDate, address.addressLines, application.lenderID,address.postcode) "
+ " from Application as application inner join application.applicants applicant, applicant.addresses address
My question is, what is the syntax I need to add to query on the first element of the address collection, bearing in mind that the address collection may well be empty.
Hibernate version:
2.17
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class name="net.targetgroup.broker.address.Address" table="ADDRESS">
<id name="identifier" type="int" column="ADDRID" unsaved-value="-1">
<generator class="native" />
</id>
<property name="addressLines" type="net.targetgroup.broker.address.AddressLinesUserType">
<column name="ADDR01" />
<column name="ADDR02" />
<column name="ADDR03" />
<column name="ADDR04" />
<column name="ADDR05" />
</property>
<property name="postcode" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="POSTCODE" length="8" />
<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="timeStamp" type="java.sql.Timestamp" column="DATETIME" length="19" />
<joined-subclass name="net.targetgroup.broker.customer.CustomerAddress" table="CORR_ADDR">
<key>
<column name="ADDRID" />
</key>
<property name="customerIdentifier" type="java.math.BigDecimal" column="CUSTID" length="9" />
<property name="userStamp" type="java.lang.String" column="USERSTAMP" length="10" />
<property name="addressType" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="ADDRTYPE" length="30" />
<property name="timeStamp" type="java.sql.Timestamp" column="DATETIME" length="26" />
<property name="movedInDate" type="java.sql.Timestamp" column="MOVEDIN" length="26" />
<property name="votersRoll" type="net.targetgroup.util.datatypes.CustomBooleanType" column="VOTERSROLL" length="1" />
<property name="movedOutDate" type="java.sql.Timestamp" column="MOVEDOUT" length="26" />
<property name="votersStartDate" type="java.sql.Date" column="VOTERSIN" length="10" />
<property name="ownStatus" type="net.targetgroup.util.datatypes.CustomStringTrimType" column="OWNERSHIPSTATUS" length="40" />
<property name="votersEndDate" type="java.sql.Date" column="VOTERSOUT" length="10" />
</joined-subclass>
</class>
</hibernate-mapping>
/*
* AddressLinesUserType.java
*/
package net.targetgroup.broker.address;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.sf.hibernate.CompositeUserType;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.type.Type;
import net.targetgroup.util.db.hibernate.UserType;
import org.apache.commons.lang.StringUtils;
/**
*
* @author pauln
*
* THis class is used to map from a List of address lines to the separate address fields on the database
*
*/
public class AddressLinesUserType extends UserType {
private static final int[] TYPES =
{ Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR, Types.CHAR };
public static final int LINES = 5;
/**
* @return
*/
public int[] sqlTypes() {
return TYPES;
}
/**
* @see net.sf.hibernate.CompositeUserType#returnedClass()
*/
public Class returnedClass() {
return String[].class;
}
/**
* @see net.sf.hibernate.CompositeUserType#equals(java.lang.Object, java.lang.Object)
*/
public boolean equals(Object x, Object y) {
if (x == y)
return true;
if (x == null || y == null)
return false;
List xl = (List) x;
List yl = (List) y;
// Can't be the same if different sizes
if (xl.size() != yl.size()) {
return false;
}
// have a look at the contents
Iterator iterX = xl.iterator();
for (Iterator iterY = yl.iterator(); iterY.hasNext();) {
String stringY = (String) iterY.next();
String stringX = (String) iterX.next();
if (!stringX.equals(stringY)) {
return false;
}
}
return true;
}
/**
* @see net.sf.hibernate.CompositeUserType#deepCopy(java.lang.Object)
*/
public Object deepCopy(Object x) {
if (x == null)
return null;
List input = (List) x;
List result = new ArrayList(input);
return result;
}
/**
* @see net.sf.hibernate.CompositeUserType#isMutable()
*/
public boolean isMutable() {
return true;
}
/**
* @see net.sf.hibernate.CompositeUserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], net.sf.hibernate.engine.SessionImplementor, java.lang.Object)
*/
public Object nullSafeGet(
ResultSet rs,
String[] names,
SessionImplementor session,
Object owner)
throws HibernateException, SQLException {
List list = new ArrayList();
for (int i = 0; i < LINES; i++) {
String line = (String) Hibernate.STRING.nullSafeGet(rs, names[i]);
if(line==null) {
line=new String("");
}
list.add(StringUtils.trim(line));
}
return list;
}
/**
* @see net.sf.hibernate.CompositeUserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int, net.sf.hibernate.engine.SessionImplementor)
*/
public void nullSafeSet(
PreparedStatement st,
Object value,
int index,
SessionImplementor session)
throws HibernateException, SQLException {
List list = (value == null) ? new ArrayList(LINES) : (List) value;
for (int i = 0; i < LINES; i++) {
Object listItem = null;
if (i < list.size()) {
listItem = list.get(i);
} else {
listItem = null;
}
Hibernate.STRING.nullSafeSet(st, listItem, index++);
}
}
/**
* @see net.sf.hibernate.CompositeUserType#getPropertyNames()
*/
public String[] getPropertyNames() {
return new String[] {
"addressLine1",
"addressLine2",
"addressLine3",
"addressLine4",
"addressLine5" };
}
/**
* @see net.sf.hibernate.CompositeUserType#getPropertyTypes()
*/
public Type[] getPropertyTypes() {
return new Type[] {
Hibernate.STRING,
Hibernate.STRING,
Hibernate.STRING,
Hibernate.STRING,
Hibernate.STRING };
}
/**
* @see net.sf.hibernate.CompositeUserType#getPropertyValue(java.lang.Object, int)
*/
public Object getPropertyValue(Object component, int property) {
return component;
}
/**
* @see net.sf.hibernate.CompositeUserType#setPropertyValue(java.lang.Object, int, java.lang.Object)
*/
public void setPropertyValue(
Object component,
int property,
Object value) {
component = value;
}
/**
* @see net.sf.hibernate.CompositeUserType#assemble(java.io.Serializable, net.sf.hibernate.engine.SessionImplementor, java.lang.Object)
*/
public Object assemble(
Serializable cached,
SessionImplementor session,
Object owner) {
return deepCopy(cached);
}
/**
* @see net.sf.hibernate.CompositeUserType#disassemble(java.lang.Object, net.sf.hibernate.engine.SessionImplementor)
*/
public Serializable disassemble(Object value, SessionImplementor session) {
return (Serializable) deepCopy(value);
}
}
_________________ On the information super B road
|