2014-02-21 4 views
10

Я застрял в конкретной проблеме, используя array type в postgresql 9.3, сопоставленный спящим 4.1.0. Этот тип позволяет мне иметь действительно сильную модель данных, не создавая много таблиц и объединений.Hibernate, Postgres & Array Тип

Чтобы отобразить поле, хранящееся с этим конкретным типом, я использовал UserType

Во всяком случае, он хорошо работает с чистым Hibernate (HQL), но мне нужно также отправить SQL Native запроса в мою базу данных , Когда я это делаю, несмотря на многие попытки, я не нашел никакого способа сделать это.

Старается много синтаксиса на основе этого

String[] values = {"value1", "value2"}; 
String queryString = "SELECT * FROM instances WHERE values && :values"; 
Query query = this.getSession().createSQLQuery(queryString).addEntity(Instance.class); 
query.setParameterList("values", values); 
query.list(); 

меня Оператор не существует: текст [] & & характера изменения

Это должно дать следующий синтаксис JDBC: [ 'значение1', «значение2»] и, кажется, чтобы дать «value1» ...

Я попробовал много синтаксисов с

  • Коллекция
  • Pure Массивы
  • [: значения] Синтаксис: Я получил Синтаксическая ошибка возле "["

Мне нужно отправить родной запрос, потому что я использую Materialized View для увеличения производительности ,

Мой SQL-запрос работает в консоли postgresql. Так что это проблема спящего режима.

+1

возможно дубликат [ отображение массива postgres с hibernate] (http://stackoverflow.com/questions/1647583/mapping-a-postgres-array-with-hibernate) – borchvm

ответ

22

Я пробовал несколько версий на основе массива типа, введенного JDBC4: How can I set a String[] parameter to a native query?. Проблема также спящего режима (даже в последней версии 4.3.1.final) не работает с этим новыми возможностями и дал мне следующее сообщение об ошибке

Could not determine a type for class: org.postgresql.jdbc4.Jdbc4Array 

Так что я должен был сделать Specific UserType (на основе нескольких статей в StackOverflow и источники других)

My Model

@Type(type = "fr.mycompany.dao.hibernate.types.ArrayUserType") 
private String[] values; 

Мои ArrayUserType

public class ArrayUserType implements UserType { 

/** Constante contenant le type SQL "Array". 
*/ 
protected static final int[] SQL_TYPES = { Types.ARRAY }; 

/** 
* Return the SQL type codes for the columns mapped by this type. The 
* codes are defined on <tt>java.sql.Types</tt>. 
* 
* @return int[] the typecodes 
* @see java.sql.Types 
*/ 
public final int[] sqlTypes() { 
    return SQL_TYPES; 
} 

/** 
* The class returned by <tt>nullSafeGet()</tt>. 
* 
* @return Class 
*/ 
public final Class returnedClass() { 
    return String[].class; 
} 

/** 
* Retrieve an instance of the mapped class from a JDBC resultset. Implementors 
* should handle possibility of null values. 
* 
* @param resultSet a JDBC result set. 
* @param names the column names. 
* @param session SQL en cours. 
* @param owner the containing entity 
* @return Object 
* @throws org.hibernate.HibernateException exception levée par Hibernate 
* lors de la récupération des données. 
* @throws java.sql.SQLException exception SQL 
* levées lors de la récupération des données. 
*/ 
@Override 
public final Object nullSafeGet(
     final ResultSet resultSet, 
     final String[] names, 
     final SessionImplementor session, 
     final Object owner) throws HibernateException, SQLException { 
    if (resultSet.wasNull()) { 
     return null; 
    } 

    String[] array = (String[]) resultSet.getArray(names[0]).getArray(); 
    return array; 
} 

/** 
* Write an instance of the mapped class to a prepared statement. Implementors 
* should handle possibility of null values. A multi-column type should be written 
* to parameters starting from <tt>index</tt>. 
* 
* @param statement a JDBC prepared statement. 
* @param value the object to write 
* @param index statement parameter index 
* @param session sql en cours 
* @throws org.hibernate.HibernateException exception levée par Hibernate 
* lors de la récupération des données. 
* @throws java.sql.SQLException exception SQL 
* levées lors de la récupération des données. 
*/ 
@Override 
public final void nullSafeSet(final PreparedStatement statement, final Object value, 
     final int index, final SessionImplementor session) throws HibernateException, SQLException { 

    if (value == null) { 
     statement.setNull(index, SQL_TYPES[0]); 
    } else { 
     String[] castObject = (String[]) value; 
     Array array = session.connection().createArrayOf("text", castObject); 
     statement.setArray(index, array); 
    } 
} 

@Override 
public final Object deepCopy(final Object value) throws HibernateException { 
    return value; 
} 

@Override 
public final boolean isMutable() { 
    return false; 
} 

@Override 
public final Object assemble(final Serializable arg0, final Object arg1) 
     throws HibernateException { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public final Serializable disassemble(final Object arg0) throws HibernateException { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public final boolean equals(final Object x, final Object y) throws HibernateException { 
    if (x == y) { 
     return true; 
    } else if (x == null || y == null) { 
     return false; 
    } else { 
     return x.equals(y); 
    } 
} 

@Override 
public final int hashCode(final Object x) throws HibernateException { 
    return x.hashCode(); 
} 

@Override 
public final Object replace(
    final Object original, 
    final Object target, 
    final Object owner) throws HibernateException { 
    return original; 
} 

}

И последнее, но не менее (это то, что я пропустил): когда мне нужно запустить SQL Native запрос, я должен заставить тип параметра со следующим синтаксисом

String[] values = ... 
Type arrayType = new CustomType(new ArrayUserType()); 
query.setParameter("value", values, arrayType); 
+0

Очень полезно, спасибо! – cslotty

+0

Какова лицензия для этого кода? Я хочу использовать его в приложении GPL. – z0r

+0

Ничего, я, вероятно, переопределю его, используя CompositeUserType и ParameterizedType. – z0r

Смежные вопросы