Подтвердить что ты не робот

Ленько загружая клобу в спящий режим

Там можно многое узнать по этому вопросу, но я не нашел эффективного решения этой проблемы.

В принципе, у меня есть большой CLOB для определенного класса, который я хочу загрузить по требованию. Наивный способ сделать это:

class MyType {

  // ...

  @Basic(fetch=FetchType.LAZY)
  @Lob
  public String getBlob() {
    return blob;
  }
}

Это не работает, по-видимому, из-за того, что я использую драйверы oracle, т.е. объекты Lob не рассматриваются как простые дескрипторы, но всегда загружаются. Или так мне верили из моих набегов. Существует одно решение, которое использует специальные инструменты для загрузки ленивых свойств, но, как показывают документы Hibernate, они менее заинтересованы в правильном выполнении этой работы, поэтому я предпочел бы не идти по этому маршруту. Особенно с необходимостью запуска дополнительного компиляционного прохода и всего.

Итак, следующее решение, которое я предполагал, это отделить этот объект от другого типа и определить связь. К сожалению, хотя документы дают противоречивую информацию, мне кажется, что ленивая загрузка не работает с ассоциациями OneToOne с общим первичным ключом. Я установил бы одну сторону ассоциации как ManyToOne, но я не совсем уверен, как это сделать, когда есть общий первичный ключ.

Так может ли кто-нибудь предложить лучший способ сделать это?

4b9b3361

Ответ 1

Согласно this, только PostgreSQL реализует Blob как действительно ленивый. Поэтому лучшим решением является перемещение blob в другую таблицу. Вам нужно использовать общий первичный ключ? Почему бы вам не сделать что-то вроде этого:

public class MyBlobWrapper {
    @Id
    public Long getId() {
       return id;
    }
    @Lob
    public String getBlob() {
        return blob;
    }
    @OneToOne(fetch=FetchType.LAZY,optional=false) 
    public MyClass getParent() {
        return parent;
    }
}

Ответ 2

Вместо выполнения уравновешенности с аннотациями спящего режима можно просто попытаться преобразовать поле из String в Clob (или Blob):

@Lob  
@Basic(fetch=FetchType.LAZY)  
@Column(name = "FIELD_COLUMN")  
public Clob getFieldClob() {  
  return fieldClob;  
}  

public void setFieldClob(Clob fieldClob) {  
  this.fieldClob = fieldClob;  
}  

@Transient  
public String getField()  
{  
  if (this.getFieldClob()==null){  
    return null;  
  }  
  try {  
    return MyOwnUtils.readStream(this.getFieldClob().getCharacterStream());  
  } catch (Exception e) {  
    e.printStackTrace();  
  }  

  return null;  
}  

public void setField(String field)  
{  
  this.fieldClob = Hibernate.createClob(field);  
} 

Работала для меня (поле начинало лениво загружаться, на Oracle).

Ответ 3

Поскольку вы, кажется, используете Hibernate, я задаюсь вопросом, связана ли ваша проблема со следующей функцией Hibernate:

Использование Lazy Properties Fetching

Hibernate3 поддерживает ленивую выборку отдельных свойств. Эта метод оптимизации также известен как группы выборки. Обратите внимание, что это в основном маркетинговая функция; оптимизация чтения строк намного больше что важно, чем оптимизация чтения столбцов. Однако только загрузка некоторые свойства класса могут быть полезны в крайних случаях. Для Например, когда унаследованные таблицы содержат сотни столбцов и данные модель не может быть улучшена.

Ложная загрузка свойств требует встроенного инструментария байт-кода. Если ваши постоянные классы не будут расширены, Hibernate будет игнорировать ленивый настройки свойств и вернуться к немедленной выборке.

См. Инструмент Bytecode для спящего режима с использованием Maven.