Невозможно вставить NULL в столбец - PullRequest
3 голосов
/ 01 сентября 2011

Я пытаюсь заставить Hibernate лениво загрузить некоторые сабы.Загрузочная часть работает просто отлично.Проблема в том, когда я пытаюсь создать новый.Я начал с совета от Blob lazy loading

Вот мои отображения (Обратите внимание, что структура таблицы действительно очень плохая, в этой таблице несколько сгустков - этот пример упрощен от моего реальногомодель ...).

@Entity @Table("TABLE_1")
public class BadDBDesign {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column("table_id")
  private long key;

  @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  @JoinColumn(name = "table_id", referencedColumnName = "table_id", 
              insertable = true, updatable = false)
  private BlobWrapperA;

  @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
  @JoinColumn(name = "table_id", referencedColumnName = "table_id",
              insertable = true, updatable = false)
  private BlobWrapperB;
}

@Entity @Table(name = "TABLE_1")
public class BlobWrapperA {
  @Lob
  @Column(name = "col_A", nullable = false)
  @Type(type = "org.springframework.orm.hibernate3.support.BlobByteArrayType")
  private byte[] blobColA;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "table_id")
  private long Key;
}

@Entity @Table(name = "TABLE_1")
public class BlobWrapperB {
  @Lob
  @Column(name = "col_B", nullable = false)
  @Type(type = "org.springframework.orm.hibernate3.support.BlobByteArrayType")
  private byte[] blobColB;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "table_id")
  private long Key;
}

Приложение загружается просто отлично, я могу получить данные без загрузки сгустков (могу получить их при необходимости с помощью отложенной загрузки), но когда я пытаюсь создатьновые я получаю следующую трассировку стека:

Hibernate: 
  insert 
  into
    TABLE_1
    (key, col_A, col_B) 
values
    (?, ?, ?)
2011-08-31 17:35:09,089 [http-8080-1] DEBUG org.springframework.jdbc.support.lob.DefaultLobHandler IP134.167.141.34 CV#f2a597b2-a185-4e89 P#71252 - Set bytes for BLOB with length 7136
2011-08-31 17:35:16,441 [http-8080-1] DEBUG org.springframework.jdbc.support.lob.DefaultLobHandler IP134.167.141.34 CV#f2a597b2-a185-4e89 P#71252 - Set bytes for BLOB with length 10946
Aug 31, 2011 5:35:50 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet online threw exception java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("SCHEMA"."TABLE_1"."COL_A")

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1010)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3657)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)

Обратите внимание на важную часть, где мы видим длины сгустков сразу после оператора вставки Hibernate из сгенерированного SQL.

Редактировать: Посмотрев на это рано утром, я понял, что проблема была в том, что один из BLOB-объектов должен был отображаться с помощью @JoinColumn (inserttable = false, updatable = false), иначе Hibernate не запустится.Таким образом, конечно, он пытался вставить Null в этот столбец.Таким образом, возникает новый вопрос, можете ли вы лениво MULTIPLE сгустки на одной таблице (используя тот же ключ).Я предполагаю, что без редизайна таблицы мне не повезет, если Oracle не исправит драйвер.

Ответы [ 3 ]

3 голосов
/ 07 сентября 2011

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

Таким образом, я вытащил общие части в абстрактный класс, как например:

@MappedSuperclass @Table("TABLE_1")
public class BadDBDesign {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column("table_id")
  private long key;

  @Column("small_value")
  private String smallVarChar2Field;
}

Проблема в том, что мне нужно расширить этот класс для каждого из наших BLOB-объектов :( Таким образом, наши расширенные классы выглядят так:

public class BlobA extends BadDBDesign {
  @Lob @Column("col_a")
  @Type(type ="org.springframework.orm.hibernate3.support.BlobByteArrayType")
  private byte[] blobColA;
}

public class BlobB extends BadDBDesign {
  @Lob @Column("col_b")
  @Type(type ="org.springframework.orm.hibernate3.support.BlobByteArrayType")
  private byte[] blobColB;
}

К счастью, у нас нет места, где мы больше одногоclob на любой странице. Это все еще кошмар обслуживания, но он был приемлемым компромиссом (пока что) для более эффективного выполнения нагрузок. Я создал DAO для них, которых у проекта не было раньше;надеюсь, это подтолкнет команду в правильном направлении к правильному уровню абстракции, и мы надеемся, что мы сможем полностью удалить эти потерянные POJO в следующем выпуске.

0 голосов
/ 01 сентября 2011

Oracle и Hibernate ненавидят друг друга, когда дело касается типов больших объектов, что связано с тем, что драйвер Oracle является мусором.Я полагаю, что я сталкивался с этим раньше, вы должны попробовать установить следующие системные свойства:

hibernate.jdbc.use_streams_for_binary=true
hibernate.jdbc.batch_size=0
0 голосов
/ 01 сентября 2011

Похоже, в вашем классе BlobWrapperA для этого столбца установлено значение "nullable = false". Или столбец имеет нулевое ограничение для самой таблицы в базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...