Условное отображение в Hibernate 3.0? - PullRequest
2 голосов
/ 06 июля 2010

Как создать отображение в hibernate, которое зависит от свойства type, вставить / извлечь данные в / из соответствующего столбца.

Структура:

СТОЛОВЫЕ КОЛОННЫ:

|TYPE | CHARACTER | DATE | TIME | NUMERIC|

POJO:

class Pojo {

 private int type;
 private Object data;

 ...

}

Примеры:

  • Insert / Update
    Если тип равен 1, мы вводим значение в столбец CHARACTER

  • Выберите
    Если тип равен 2, мы получаем значение из столбца NUMERIC

СОВЕТ: Структура, в которой у нас есть два столбца и мы PIVOT, результат не подходит для этого случая.

Ответы [ 2 ]

2 голосов
/ 16 августа 2010

Решением, которое я выбрал для этого, является отображение таблицы на иерархию классов с целочисленным дискриминатором.

Я создал базовый абстрактный обобщенный класс, в котором хранится объект

 public abstract class ValueBase<T> {

   private Long id; 
   private int valueType;
   private T value;

   public T getValue(){
     return value;
   }

   public void setValue(T value){
     this.value = value;
   }

   protected void setValueType(int valueType) {
      this.valueType = valueType;
   }

   public int getValueType(){
     return this.valueType;
   }

   private void setID(Long id) {
      this.id = id;
   }

   public int getID(){
     return this.id;
   }


 }

Для управления типами я создал и интерфейс, но есть возможность перечисления с использованием инкапсуляции, представленной Артуром.

public interface IValueTypes() {

 public static final int NONE = -1;
 public static final int NUMERIC = 0;
 public static final int CHARACTER = 1;
 public static final int DATE = 2;
 public static final int TIME = 3;
 public static final int BOOLEAN = 4;

}

Класс для каждого типа, который я создал,

 public class NumericType extedns ValueBase<BigDecinal> {

    public NumericType(){
      super();
      setValueType(IValueTypes.NUMERIC);
    }

 }

 public class CharacterType extedns ValueBase<String> {

    public NumericType(){
      super();
      setValueType(IValueTypes.CHARACTER);
    }

 }

СОВЕТ: Чтобы разрешить использовать число в качестве значения дискриминатора, нам нужно сначала указать его для отображаемого нами класса, потому что по умолчанию используется имя класса [String] и мы пытаемся использовать числовой дискриминатор для отображения подклассов, мы получим ошибку гибернации, которая говорит о некотором несоответствии типов.

<class name="TestValue" table="TestValues" schema="TEST" abstract="true" discriminator-value="-1"> 
  <id name="id" type="java.lang.Long">
    <column name="VALUE_ID" precision="22" scale="0" />
    <generator class="native"/>
  </id>

  <discriminator column="TYPE_VALUE" not-null="false" type="integer"/> 

  <subclass discriminator-value="0" name="NumericType">
    <property name="value" type="java.math.BigDecimal" column="NUMERIC" not-null="false"/>
  </subclass>   

  <subclass discriminator-value="1" name="CharacterType">
    <property name="value" type="java.lang.String" column="CHARACTER" not-null="false"/>
  </subclass>   

</class>

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

1 голос
/ 14 августа 2010

Такое поведение достигается с помощью инкапсуляции .Например, у меня есть столбец String (Y / N) в базе данных (INSERT / UPDATE), который инкапсулирован логическим (SELECT) следующим образом

public class SomeEntity {

    private boolean checked;

    private boolean isChecked() {
        return this.checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
    }

    public String getCheckedAsString() {
        return checked ? "Y" : "N";
    }

    public void setCheckedAsString(String checked) {
        this.checked = checked.equals("Y") ? true : false;
    }

}

Ваше отображение идет сюда

<property name="checkedAsString" type="string" column="CHECKED"/>

Эта стратегия объясняется здесь Я использовал помимо преобразования в качестве обходного пути Разрешить использование ключевых слов Java String в качестве Enum.Смотри здесь

...