Dea*_*eam 4 select hibernate insert one-to-one
我是Hibernate的新手.我有一个问题,当我试图运行选择查询说
"from Foo where Foo.some_id=2"
Run Code Online (Sandbox Code Playgroud)
(使用Hibernate模板)然后Hibernate也尝试将记录插入到表'Foo2'中,该表与Foo表具有一对二的关联
Bean Foo
class Foo{
int id;
....
Foo2 foo2;
}
Run Code Online (Sandbox Code Playgroud)
Foo.hbm.xml
...
<one-to-one name="foo2" class="Foo2" property-ref="foo"
constrained="false" cascade="save-update"></one-to-one>
...
Run Code Online (Sandbox Code Playgroud)
Bean Foo2
Class Foo2{
...
private int foo;
...
}
Run Code Online (Sandbox Code Playgroud)
Foo2.hbm.xml
...
<property name="foo" column="foo_id"/>
...
Run Code Online (Sandbox Code Playgroud)
用法
DetachedCriteria criteria = createDetachedCriteria();
criteria.add(Restrictions.eq("some_id", value));
return getHibernateTemplate().findByCriteria(criteria);
public List<SnsUser> getAllSnsUsersByProperty(String prop, Object val){
String query = "from SnsUser su where su." + prop + " =:" + prop;
return executeQuery(query, new String[]{prop}, new Object[]{val});
}
public static void main(String[] args) { //WORKING
String query = "from SnsUser su where su.blessUserId=1";
Session session = Utility.getSessionFactory().openSession();
List l = new SnsUserDaoImpl().getQRes(query);
System.out.println(l);
session.close();
}
public List<E> executeQuery(String queryString, String []param, Object [] val){
//NOT WORKING
return getHibernateTemplate().findByNamedParam(queryString, param, val);
}
Run Code Online (Sandbox Code Playgroud)
这就是我得到的......
Hibernate: select * from bless_aggregation.sns_user this_ left outer join bless_aggregation.sns_authenticator snsauthent2_ on this_.sns_uid=snsauthent2_.sns_uid
where this_.bless_uid=?
Hibernate: select * from bless_aggregation.bless_user blessuser0_ where blessuser0_.bless_uid=?
Hibernate: select * from bless_aggregation.sns_user snsuser0_ left outer join bless_aggregation.sns_authenticator snsauthent1_ on
snsuser0_.sns_uid=snsauthent1_.sns_uid where snsuser0_.bless_uid=?
Hibernate: insert into bless_aggregation.sns_authenticator (key, value, sns_uid) values (?, ?, ?)
1079 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1064, SQLState: 42000
1079 [main] ERROR org.hibernate.util.JDBCExceptionReporter - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key, value, sns_uid) values (null, null, 1)' at line 1
Run Code Online (Sandbox Code Playgroud)
我的猜测是你在会话中有待更改(一些Foo2实例等待插入),默认情况下,Hibernate会在运行查询之前刷新会话,以便为您提供非陈旧的结果.这在文档的以下部分中进行了解释:
10.10.刷新会话
有时,Session将执行将JDBC连接的状态与内存中保存的对象状态同步所需的SQL语句.此过程称为刷新,默认情况下发生在以下几点:
- 在一些查询执行之前
- 来自org.hibernate.Transaction.commit()
- 来自Session.flush()
SQL语句按以下顺序发出:
- 所有实体插入的顺序与使用相应对象保存的顺序相同
Session.save()- 所有实体更新
- 所有集合删除
- 所有集合元素删除,更新和插入
- 所有集合插入
- 使用相应对象删除相同对象的所有实体删除
Session.delete()一个例外是在保存时会插入使用本机ID生成的对象.
除非您明确说明
flush(),否则绝对不能保证Session何时执行JDBC调用,只保证它们执行的顺序.但是,Hibernate确保Query.list(..)永远不会返回过时或不正确的数据.可以更改默认行为,以便更频繁地进行刷新.的
FlushMode类定义了三种不同的模式:仅刷新在提交时用于Hibernate的Transaction API时,自动冲水使用解释程序中,或从未除非冲洗冲洗()被明确地调用.最后一种模式对于长时间运行的工作单元很有用,其中会话保持打开和断开很长时间(参见第11.3.2节"扩展会话和自动版本控制").Run Code Online (Sandbox Code Playgroud)sess = sf.openSession(); Transaction tx = sess.beginTransaction(); sess.setFlushMode(FlushMode.COMMIT);//允许查询返回失效状态
Run Code Online (Sandbox Code Playgroud)Cat izi = (Cat) sess.load(Cat.class, id); izi.setName(iznizi); // might return stale data sess.find("from Cat as cat left outer join cat.kittens kitten"); // change to izi is not flushed! ... tx.commit(); // flush occurs sess.close();在刷新期间,可能会发生异常(例如,如果DML操作违反约束).由于处理异常涉及对Hibernate的事务行为的一些理解,因此我们将在第11章"事务和并发"中讨论它.
因此,如上所述并如代码段所示,请尝试使用FlushMode.COMMIT.
请注意,如果您使用的是identity生成器,这将无济于事,Hibernate会save及时写入数据库.
另外请注意,FlushMode仅仅是一个暗示了Session,该行为不是严格的保证.
| 归档时间: |
|
| 查看次数: |
3819 次 |
| 最近记录: |