hibernate_ejb3笔记
1、用MyEclipse通过连接到数据库,可以生成Hibernate需要的POJO和对应的映射文件。但是我生成的hbm.xml有问题,会报错"could not load an entity"。后来找到了元凶
<
class
name
=
"
hbm.pojo.Misuser
"
table
=
"
misuser
"
schema
=
"
informix
"
catalog
="
zzymis"
>
把catalog="zzymis"去掉就OK了。
2、Hibrenate保存数据失败
如果忘记提交事务会导致数据保存或者更新失败,正确代码如下:
HibernateSessionFactory. getSession().beginTransaction();
new hbm.pojo.StudySubjectDAO().merge(subject);
HibernateSessionFactory. getSession().flush();
HibernateSessionFactory. getSession().getTransaction().commit();
HibernateSessionFactory. getSession().beginTransaction();
new hbm.pojo.StudySubjectDAO().merge(subject);
HibernateSessionFactory. getSession().flush();
HibernateSessionFactory. getSession().getTransaction().commit();
3、Hibernate一对多的配置
最好使用双向关联(假设Main
->
Detail)
1 )Main.java中加入:
private Set < Detail > detail = new HashSet();
然后加入get()和set()方法;
2 )Detail.java中加入:
private Main main;
然后加入get()和set()方法;另外别忘了重写equals()方法
public boolean equals(Object object) {
if (object == null || !this.getClass().equals(object.getClass())) {
return false;
}
Detail other = (Detail)object;
if(other.id==null||this.id==null)
return false;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id)))
return false;
return true;
}
3 )Main.hbm.xml中加入:
< set name = " detail " inverse = " true " cascade = " all " >
< key column = " mainId " ></ key >
< one - to - many class = " Detail " />
</ set >
4 )Detail.hbm.xml中加入:
< many - to - one name = " main " class = " Main " column = " mainId " >
</ many - to - one >
同时把mainId对应的 < property > …… </ property > 删掉
5 )操作:
双向设置:(调用setMain()setDetail())
1 )Main.java中加入:
private Set < Detail > detail = new HashSet();
然后加入get()和set()方法;
2 )Detail.java中加入:
private Main main;
然后加入get()和set()方法;另外别忘了重写equals()方法
public boolean equals(Object object) {
if (object == null || !this.getClass().equals(object.getClass())) {
return false;
}
Detail other = (Detail)object;
if(other.id==null||this.id==null)
return false;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id)))
return false;
return true;
}
3 )Main.hbm.xml中加入:
< set name = " detail " inverse = " true " cascade = " all " >
< key column = " mainId " ></ key >
< one - to - many class = " Detail " />
</ set >
4 )Detail.hbm.xml中加入:
< many - to - one name = " main " class = " Main " column = " mainId " >
</ many - to - one >
同时把mainId对应的 < property > …… </ property > 删掉
5 )操作:
双向设置:(调用setMain()setDetail())
4、EJB中的getSingleResult()方法
查找返回一个结果,是唯一的一个结果,当getSingleResult()个方法被调用时执行查询。如果没有结果返回,这个方法将会抛出javax.persistence.EntityNotFoundException运行异常.如果找到多于一个结果, javax.persistence.NonUniqueResultException异常将会在运行期间抛出.因为这两个异常都是RuntimeException,例子中的代码不需要完整的try/catch块。
5、Hibernate3的解决中文查询问题
如果直接把查询的参数放到sql语句中是查不出来的,比如:
Query query = em.createQuery(" select u from User u where u.name like ' %"+myName+"% ' ");
可以使用占位符或者设置参数的方法来查询,例如:
1 )Query query = em.createQuery(" select u from User u where u.name like ? ");
query.setString( 0 ," % " + myName + " % ");
2 )Query query = em.createQuery(" select u from User u where u.name like :name");
query.setString("name"," % " + myName + " % ");
Query query = em.createQuery(" select u from User u where u.name like ' %"+myName+"% ' ");
可以使用占位符或者设置参数的方法来查询,例如:
1 )Query query = em.createQuery(" select u from User u where u.name like ? ");
query.setString( 0 ," % " + myName + " % ");
2 )Query query = em.createQuery(" select u from User u where u.name like :name");
query.setString("name"," % " + myName + " % ");
6、Like的其他用法(正则)
like
'
_heryl
'
:搜索以字母 heryl 结尾的所有六个字母的名称(如 Cheryl、Sheryl)。
like ' [CK]ars[eo]n ' :搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。
like ' [M-Z]inger ' :搜索以字符串 inger 结尾、以从M到Z的任何单个字母开头的所有名称如 。
like ' M[^c]% ' :搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如 MacFeather)。
like ' [CK]ars[eo]n ' :搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。
like ' [M-Z]inger ' :搜索以字符串 inger 结尾、以从M到Z的任何单个字母开头的所有名称如 。
like ' M[^c]% ' :搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如 MacFeather)。
7、一对多(one-to-many)删除不掉
比如Main-to-Detail是one-to-many关系,在新增的时候可以通过persistMain()同时把多个Detail插入数据库,但是如果想删除某个Main中的某几个Detail时,好像通过mergeMain()是无法做到的,通过mergeMain()可以更新Main的属性,但是没办法删除相应的Detail,至少我是没办法做到。这时,我一半都是写个方法单独来删除Detail,例如deleteDetailById()来一个个删除。
8、查询返回多个实体Bean
1
)查询(省略后的代码)
@PersistenceContext(unitName = " crm " )
private EntityManager em;
public List getUserinfoTrace(){
return em.createQuery( " select new List(u,t) from Userinfo u,Trace t where u.id=t.id " ).getResultList();
}
2 )读取(省略后的代码)
List < List > result = (List < List > )remote.getUserinfoTrace();
for (List obj:result){
Userinfo userinfo = (Userinfo)result.get( 0 );
Trace trace = (Trace)result.get( 1 );
……
}
@PersistenceContext(unitName = " crm " )
private EntityManager em;
public List getUserinfoTrace(){
return em.createQuery( " select new List(u,t) from Userinfo u,Trace t where u.id=t.id " ).getResultList();
}
2 )读取(省略后的代码)
List < List > result = (List < List > )remote.getUserinfoTrace();
for (List obj:result){
Userinfo userinfo = (Userinfo)result.get( 0 );
Trace trace = (Trace)result.get( 1 );
……
}
9、设置ID自增
在用netbean生成的实体Bean后,需要手工加上自增注释(@GeneratedValue(strategy = GenerationType.AUTO))
例如:
@Id
@Column(name = " id " , nullable = false )
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
例如:
@Id
@Column(name = " id " , nullable = false )
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
10、failed to lazily initialize a collection of role
因为延迟加载导致的,但是我在EntityBean中使用fetch=FetchType.EAGER和FetchType.LAZY都无效,我的EntityBean是@OneToMany,最后只有在SessionBean的读取EntityBean的方法中加入:
if
(main.getDetails()
!=
null
)
main.getDetails().size();
return main;
这样总算解决问题。
main.getDetails().size();
return main;