Может ли Hibernate автоматически вводить верхний регистр столбца при чтении / вставке через конфигурацию? - PullRequest
8 голосов
/ 08 марта 2010

У нас есть несколько столбцов с данными, которые всегда должны быть в верхнем регистре, чтобы обеспечить уникальность. Мне было интересно, если hibernate может заставить все такие столбцы в верхний регистр через некоторые изменения файла конфигурации?

На самом деле мы используем пользовательский тип пользователя для шифрования / дешифрования данных столбца для какой-то другой таблицы, но я подумал, что было бы излишне просто писать все в верхнем регистре ...

В качестве альтернативы я думал об изменении моделей таким образом, чтобы все геттеры / сеттеры в верхнем и нижнем регистре вводили и отправляли любую строку.

В худшем (?) Случае следует изменить ограничение столбца Oracle, чтобы игнорировать регистр при проверке уникальности.

Есть мысли?

Ответы [ 5 ]

6 голосов
/ 15 апреля 2016

Гораздо чище подход:

@Column(name = "DUMMY")
@ColumnTransformer(read = "UPPER(DUMMY)")
private String dummy
3 голосов
/ 09 марта 2010

Несколько решений:

  1. Использовать триггер базы данных (но не через конфигурацию).
  2. Изменить геттер / сеттеры (но не через конфигурацию).
  3. Используйте UserType для преобразования атрибута в верхний регистр.
  4. Используйте перехватчик или прослушиватель событий .

Решение № 1 прозрачно для кода, но я не большой поклонник триггеров «за вашей спиной», и я не люблю распространять бизнес-правила повсеместно. Решения № 3 и № 4 зависят от Hibernate (но это может и не быть проблемой). Решение № 2 - самое простое и портативное решение, если вы можете изменить код. Это был бы мой выбор, если это вариант.

1 голос
/ 10 марта 2010

Я решил реализовать UserType ... он настолько близок к конфигурации гибернации, насколько я могу себе представить ... вот код ...

package model;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class UpperCaseUserType implements UserType {
    private static final int[] TYPES = {Types.VARCHAR};

public int[] sqlTypes() {
        return TYPES;
}

public Class returnedClass() {
        return String.class;
}

public boolean equals(Object x, Object y) throws HibernateException {
        if (x == y) {
            return true;
        }
        if (null == x || null == y) {
            return false;
        }
        return new EqualsBuilder().append(x, y).isEquals();
}

public int hashCode(Object o) throws HibernateException {
        return new HashCodeBuilder().append(o).toHashCode();
}

public Object nullSafeGet(ResultSet resultSet, String[] strings, Object object) throws HibernateException, SQLException {
        return ((String) Hibernate.STRING.nullSafeGet(resultSet, strings[0])).toUpperCase();
}

public void nullSafeSet(PreparedStatement preparedStatement, Object object, int i) throws HibernateException, SQLException {
        String string = ((String) object).toUpperCase();
        Hibernate.STRING.nullSafeSet(preparedStatement, string, i);
}

public Object deepCopy(Object o) throws HibernateException {
        if (null == o) {
            return null;
        }
        return new String(o.toString());
}

public boolean isMutable() {
        return false;
}

public Serializable disassemble(Object o) throws HibernateException {
        return (String) o;
}

public Object assemble(Serializable serializable, Object o) throws HibernateException {
        return serializable;
}

public Object replace(Object o, Object arg1, Object arg2) throws HibernateException {
        return o;
}
}

Рассмотреть этот элемент свойства

<property name="serialNumber" type="model.UpperCaseUserType">
    <column name="SERIAL_NUMBER" length="20" not-null="true" unique="true" />
</property>

Итак, рассуждение ... Когда hibernate вставляет данные, этот тип преобразует строку в верхний регистр. Когда Hibernate выбирает данные, происходит то же самое. Преимущество этого класса перед простым изменением get / set bean-компонента на прописные все, когда я использую Критерии для выбора в serialNumber. Hibernate также будет прописывать мой параметр в верхнем регистре, так как он будет приводить / применять тот же тип, который определен в конфигурации таблицы.

Поэтому мне не нужно помнить, чтобы вручную прописывать все мои критерии поиска серийных номеров ... hibernate позаботился об этом за меня ... это именно то, чего я пытаюсь достичь здесь!

У меня есть JUnit, который демонстрирует все это, но я думаю, что мой ответ слишком велик ...

1 голос
/ 08 марта 2010

Мне неизвестны какие-либо параметры конфигурации, чтобы сделать это возможным. Однако вы можете попробовать использовать перехватчик для исправления данных при вставке / обновлении, например:

package interceptor;

import java.io.Serializable;

import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

public class CustomSaveInterceptor extends EmptyInterceptor {
    public boolean onSave(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types)
    {
        if (entity instanceof MyClass) {
            MyClass myInstance = (MyClass)entity;
            myInstance.setName(myInstance.getName().toUpperCase());
        }
        return super.onSave(entity, id, state, propertyNames, types);
    }
}
0 голосов
/ 09 марта 2010

Предлагаю проверить эту страницу: http://forum.springsource.org/archive/index.php/t-18214.html

У этого есть 3 различных способа сделать это. Я считаю, что наименее навязчивый способ это:

<property name="upperCaseName" formula="upper(name)" lazy="true"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...