开发者

Cannot insert NULL into column

I am attempting to get Hibernate to lazy load some clobs. The loading portion is working just fine. The issue is when I try to create a new one. I started with advice from Blob lazy loading

Here are my mappings (Note the table structure is really really bad, there are multiple clobs on this table -- this example is simplified from my real model...).

@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;
}

Application boots just fine, am able to retrieve the data without loading the clobs (am able to retrieve them when needed via lazy loading), but when I attempt to create the new ones I receive the following stacktrace:

Hibernate: 
  insert 
  into
    TABLE_1
    (ke开发者_C百科y, 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)

Note the important piece where we see the lengths of the clobs immediately after the Hibernate insert statement from the generated SQL.

Edit: After looking at this early this morning, I realized that the issue was due to one of the Blobs had to be mapped with @JoinColumn(insertable = false, updatable = false), otherwise Hibernate would not start. As such of course it was attempting to insert Null into this column. So the new question becomes, can you lazily MULTIPLE clobs on a single table (using the same key). I'm guessing without a table redesign, I'm pretty much out of luck unless Oracle fixes the driver.


As much as it makes me want to vomit we needed to get this functionality without modifying the Database.

As such, I pulled out the common pieces into an Abstract class like such:

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

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

The problem is I then have to extend this class for each of our blobs :( Thus our extended classes loook like:

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;
}

Luckily we don't have any location where we more than one clob on any given page. This is still a maintenance nightmare, but was an acceptable trade-off (for the time-being) on getting the loads done more efficiently. I created DAO's for these, which the project didn't have prior; hopefully this will push the team in a good direction towards a proper abstraction layer, and we can hopefully completely remove these wasted POJOs in a future release.


Looks like in your BlobWrapperA class you have "nullable = false" set on that column. Or the column has a null constraint on the table itself in the database.


Oracle and Hibernate hate each other when it comes to LOB types, which stems from the fact that the Oracle driver is garbage. I believe I've run across this before, you should try setting the following system properties:

hibernate.jdbc.use_streams_for_binary=true
hibernate.jdbc.batch_size=0
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜