使用Hibernate向ORACLE数据库保存Blob字段的问题

newchengse 2008-04-30 05:22:56
我使用以下的语句保存一个newPhoto实体,其中image字段为Blob类型

Session session= HibernateSessionFactory.getSession();
Transaction tx=null;
Boolean flag=false;
try {
tx = session.beginTransaction();
//执行事务
newPhoto tempP=new newPhoto();
//先建立空的栏位
tempP.setImage(Hibernate.createBlob(new byte[1]));
System.out.println("开始保存空newPhoto");
session.save(tempP);
System.out.println("保存空newPhoto完毕");
// 执行flush,让Hibernate INSERT 空栏位
session.flush();
System.out.println("flush()完毕");
// 执行refresh,让Hibernate执行SELECT FOR UPDATE
session.refresh(tempP, LockMode.UPGRADE);
System.out.println("refresh()完毕");
tempP=p;
//session.save(tempP);
//提交事务
tx.commit();
flag=true;

}

执行到session.save(tempP);时就rollback了,也没报错,不知是什么原因?后台输出如下:
开始保存空newPhoto
17:11:00,500 DEBUG DefaultSaveOrUpdateEventListener:158 - saving transient instance
17:11:00,516 DEBUG AbstractBatcher:366 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
17:11:00,516 DEBUG SQL:401 - select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
17:11:00,516 DEBUG AbstractBatcher:484 - preparing statement
17:11:01,078 DEBUG SequenceGenerator:82 - Sequence identifier generated: 44
17:11:01,078 DEBUG AbstractBatcher:374 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
17:11:01,078 DEBUG AbstractBatcher:533 - closing statement
17:11:01,078 DEBUG AbstractSaveEventListener:112 - generated identifier: 44, using strategy: org.hibernate.id.SequenceGenerator
17:11:01,078 DEBUG AbstractSaveEventListener:153 - saving [mq.newPhoto#44]
17:11:01,110 DEBUG JDBCTransaction:152 - rollback
17:11:01,110 DEBUG JDBCTransaction:163 - rolled back JDBC Connection
17:11:01,110 DEBUG JDBCContext:215 - after transaction completion
17:11:01,110 DEBUG ConnectionManager:404 - aggressively releasing JDBC connection
17:11:01,125 DEBUG ConnectionManager:441 - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
17:11:01,125 DEBUG DriverManagerConnectionProvider:129 - returning connection to pool, pool size: 1
17:11:01,125 DEBUG SessionImpl:422 - after transaction completion
17:11:01,125 DEBUG SessionImpl:273 - closing session
17:11:01,125 DEBUG ConnectionManager:375 - connection already null in cleanup : no action


newPhoto的映谢文件如下:
<hibernate-mapping>
<class name="mq.newPhoto" table="zy_photo">

<id name="id" column="ID" type="long">
<generator class="sequence"/>
</id>

<property name="title" column="title" type="string" not-null="true" />
<property name="type" />
<property name="hits" type="int" />
<property name="description" />
<property name="image">
<column name="image" sql-type="BLOB"/>
</property>
<property name="putTime" type="timestamp"/>

</class>
</hibernate-mapping>
...全文
982 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
nanjg 2008-05-01
  • 打赏
  • 举报
回复
官方实例见这里:
http://www.hibernate.org/56.html
nanjg 2008-05-01
  • 打赏
  • 举报
回复
完整例子见下
public class MeetingHeadDAOHibernate extends BaseDAOHibernate
implements MeetingHeadDAO {
/**
* @author CZF
* Description:创建一个新的会议记要
*/
public Serializable createMeetingHead(MeetingHead mh)
throws DAOException {
try {
Session sess = HibernateHelper.currentTransaction();
Serializable result = sess.save(mh);
sess.flush();

//初始化SummaryClob字段
oracle.sql.CLOB clob = oracle.sql.CLOB.empty_lob();
mh.setSummaryClob(clob);

/*也可采用此方法进行初始化
mh.setSummaryClob (Hibernate.createClob(""));
*/

//此处一定要用lockMode.UPGRADE模式进行锁定刷新
sess.refresh(mh, LockMode.UPGRADE);

//获取MeetingHead实体的SummaryClobString属性值
String content = mh.getSummaryClobString();

//将获取的辅助字段的值通过oracle.sql.CLOB的putString()方法赋 值给实体内的summaryClob字段
oracle.sql.CLOB clob = (oracle.sql.CLOB) mh.getSummaryClob();
clob.putString(1, content);
…………
HbernateHelper.endCurrentTransaction();
return result;

nanjg 2008-05-01
  • 打赏
  • 举报
回复
 tempP.setImage(Hibernate.createBlob(new byte[1])); 

之后要行锁定。 你再对照我给你的那个教程。不过那个教程是clob的相信和blob原理一样的

 sess.refresh(mh, LockMode.UPGRADE);
nanjg 2008-05-01
  • 打赏
  • 举报
回复
给你一个很好的教程你参照下
newchengse 2008-05-01
  • 打赏
  • 举报
回复
难道五一大家都放假去玩了?郁闷
nanjg 2008-05-01
  • 打赏
  • 举报
回复
:)
newchengse 2008-05-01
  • 打赏
  • 举报
回复
谢谢楼上各位,问题已经解决。但不是按照楼上两位大哥的方法。其实我的代码没有错,而是newPhoto实例中,有个title的属性,当时在映射文件中是这样定义的:<property name="title" column="title" type="string" not-null="true" />
它定义为非空,因此我在保存空的tempP时,只设定了image属性,未设定title属性,所以存不进去。改成如下这样就可以了:
Session session= HibernateSessionFactory.getSession();
Transaction tx=null;
Boolean flag=false;
try {
tx = session.beginTransaction();
//执行事务
newPhoto tempP=new newPhoto();
//先建立空的栏位
tempP.setTitle("a");
tempP.setImage(Hibernate.createBlob(new byte[1]));
System.out.println("开始保存空newPhoto");
session.save(tempP);
System.out.println("保存空newPhoto完毕");
// 执行flush,让Hibernate INSERT 空栏位
session.flush();
System.out.println("flush()完毕");
// 执行refresh,让Hibernate执行SELECT FOR UPDATE
session.refresh(tempP, LockMode.UPGRADE);
System.out.println("refresh()完毕");
tempP=p;
session.save(tempP);
tx.commit();
flag=true;

}

只是奇怪的是,在后台没有输出错误信息。后来我把异常打印出来了:
catch (Exception e) {
//如果出现异常,就撤销事务
e.printStackTrace();
if (tx!=null) tx.rollback();
throw e;
}
这才发现问题。不过无论如何也要谢谢楼上各位的热心!
Shine_Panda 2008-05-01
  • 打赏
  • 举报
回复
try {
tx = session.beginTransaction();
//执行事务
newPhoto tempP=new newPhoto();
//先建立空的栏位
tempP.setImage(Hibernate.createBlob(new byte[1]));
System.out.println("开始保存空newPhoto");
session.save(tempP);
System.out.println("保存空newPhoto完毕");
// 执行flush,让Hibernate INSERT 空栏位
session.flush();
System.out.println("flush()完毕");
// 执行refresh,让Hibernate执行SELECT FOR UPDATE
session.refresh(tempP, LockMode.UPGRADE);
//当你锁定记录后 就通过这个对象获得他的 Blob; //xxx是你那个Blob 的字段
oracle.sql.BlOB clob = (oracle.sql.BlOB ) tempP.getXXX();
//然后获得流. //后面是什么我也记不太清楚. 你点出来看一下就是那个返回writer对象的就是了。
java.io.Writer pw = blob.getXXXXXXXXXXXX();

pw.writer(你的字节数组);
pw.close();

//提交事物就可以了.不要再次save()了
tx.commit();

flag=true;

}
newchengse 2008-04-30
  • 打赏
  • 举报
回复
这是ORACLE数据库的特殊地方,向ORACLE存储Blob类型的字段时,必须如此操作,先插入一条空,然后取出来再插入实际的内容。
nanjg 2008-04-30
  • 打赏
  • 举报
回复
2次save?

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧