hibernate笔记

 org.hibernate.MappingException: entity class not found
出现这个问题可能有两个缘由
 
一、多是hbm.xml文件没有与对象类对应
二、多是hbm.xml配置文件里的类地址指示错误
 
直接继承hibernatedaosupport可能会出现 no session的问题
解决办法:
一、直接在applicationcontext.xml文件里配置并在类里注入
二、直接在须要继承的类中写入一下代码:
   @Autowired
    public void setSessionFactoryOverride(SessionFactory sessionFactory)
    {
        super.setSessionFactory(sessionFactory);
    }
三、在ac 里注入session并由每一个实体继承
 
node to traverse cannot be null!
<property name="mappingDirectoryLocations">   
            <list>   
                <value>   
                    classpath*:/com/zhueli/soft/hr/entity/*.hbm.xml   
                </value>   
            </list>   
        </property> 
你这个地方写的不对吧,mappingDirectoryLocations属性说的就是目录位置,你为何还要*.hbm.xml   呢,指定到目录就能够了classpath*:/com/zhueli/soft/hr/entity/
 
把property的name属性值改成mappingResources。即 
<property name="mappingResources">  
            <list>  
                <value>  
                    classpath*:/com/zhueli/soft/hr/entity/*.hbm.xml  
                </value>  
            </list>  
        </property>    
 <generator class="native" />
注意这个为native才会自动插入主键

 

 主动测试时候不须要加“
save返回的是主键的值+1
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
最后记得要加上这个setter,用于转换结果为map
利用上面这个方式,能够用hibernate执行普通语句,也能够用对象来执行来操做,可是,用对象必须得配置映射文件!必须配置配置,没得商量,配置好后直接用扫描文件的方式统一加入hibernate配置文件,另外,用普通sql查出的数据,只能用map键值对方式来取值,而不能直接泛型为。
 
试试动态映射表名:
 
hbm与注解共存,须要配置为注解的class ,而后扫包方式照样
 
读取实体类映射的三种方法
mappingResources,annotatedClasses,packagesToScan(读取实体类映射)
 
 
 
另外一种能够纯sql的方法(半纯):
static List sql() {
  Session s = HibernateUtil.getSession();
  Query q = s.createSQLQuery("select * from user").addEntity(User.class);
  List<User> rs = q.list();
  s.close();
  return rs;
 }
 
hibernate的命名查询相似于mybatis
static List namedQuery(int id) {
  Session s = HibernateUtil.getSession();
  Query q = s.getNamedQuery("getUserById");
  q.setInteger("id", id);
  return q.list();
 }
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.sy.vo.User" table="user" catalog="news">
    </class>
    <!-- 命名查询:定义查询条件 -->
    <query name="getUserById">
     <![CDATA[from User where id=:id]]>
    </query>
    <!-- 命名查询中使用sql,不推荐使用,影响跨数据库
    <sql-query name="getUserById2">
     <![CDATA[select * from User where ]]>
    </sql-query> -->
</hibernate-mapping>
 
   <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory" />
    </bean>经过在配置文件里面写上这个,再在dao的实现类里面用@autowired来声明便可直接使用getHibernateTemplate对象来操做HQL语句!而表面上就脱离了hibernatedaosupport,不用再去继承了。
 
.createSQLQuery("insert into test(name) values ('测试事务333')");
记得是createSQLQuery才能执行insert,不然会values no tokens
 
String sql="select serviceAddress,versions,size from t_version where invalid=0";
    Session session=super.getHibernateTemplate().getSessionFactory().getCurrentSession();
    Query query=session.createSQLQuery(sql);
    query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
    Version ve=new Version();
    Map<String,String> map= (Map<String, String>) query.uniqueResult();

 

能够直接获取save or update 后的主键值
 
hibernate 映射配置:
单方的配置:
记得在多的一方去掉:
 
在一的一方配置:
在多的一方配置:
hbm.xml配置文件里面的类型都为hibernate的类型,须要小写,如Integer,应该为integer
one-to-one 时不须要配置column,不然会提示如下错误:
 必须为元素类型 "one-to-one" 声明属性 "column"。

object references an unsaved transient instance - save the transient instance before flushing
出现这个问题的缘由是,保存对象的时候,对象中的对象,在保存对象中的引用(仅是ID的时候)这个对象的对象不为空,可是这个对象的对象的Id却为空,因此会致使找不到Id的错误,由于对象的对象从数据库查询出来是游离状态的,当保存的时候...或者是说hibernate不容许保存没有主键的对象!
 
select gcr.id  From GesCustomerReserve gcr left join gcr.user u with u.invalid = 0 where gcr.invalid = 1 
select gescustome0_.id as col_0_0_ from base_customer_reserve gescustome0_ left outer join u_user user1_ on gescustome0_.user_id=user1_.id and (user1_.invalid=0) where gescustome0_.invalid=1 and gescustome0_.id=?
with后面只能跟上一个条件,不然会出现以下错误:with-clause referenced two different from-clause elements

 

这种方式,会在对象查询结束后生成一条单独的查询关联对象的sql语句,不一样于case when的一条关联全部内联,initialize能够实现间接的左关联方式查询html

 
list有多层属性关联的时候,用这种方式。
若是实体查询用到了left,则会为每一个left的实体生成独立的sql语句并对应于对象,结果list获得object泛型数组,object中包含若干对象
 
在left的过程当中,若是左关联致使的为空的一项做为查询条件,原本就会查询不出致使主表无数据显示,因此,条件查询中尽管用
 
gc.ooo.xxx便可!
 
record:
       //左关联并不必定要用于select中
        //list中包含三个,customer shop operator
        List<GesCustomer> temList =new ArrayList<GesCustomer>();
 
could not initialize proxy - no Session
检查下有没有加@transactional
另外,这个主要是须要获取关联的对象,可是想去获取,但是根本没有取得操做,通常的加上Hibernate.init ,或其它操做便可
这是一个精典的问题:
由于咱们在hibernate里面load一个对象出来时,用到的是代理对象,也就是说当咱们在执行load方法时并无发sql语句,而是返回一个proxy对象。只有当们具体用到哪一个get**方法时才会发sql语句,才会去数据库查。可是当咱们把打开session,关闭session交给了srping去作时,当们load完以后咱们的session就会被srping关闭,若是咱们在jsp页面或者其它的地方再去用get方法取值时就会报这个错误。
解决方法一:但若是咱们在hibernate用get方法就能够解决取单个对象的问题,由于get方法直接发sql语句,把咱们想的数据从数据库中get出来而后放在内存中。
若是咱们取单个对象能够用get方法没有问题;可是若是咱们取的的对象还有关联对象时用get就有问题,由于它不会把关联的对象取出来,但若是页面上用到关联的对象时也会报no session的问题
解决方法二:用到srping的filter(要加在strutsfilter有前面,由于它也有前后顺序,有先进先出的原则)
在咱们的web.xml里面加上
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这样作就是让opensession closesession全交给视图部分,最后视图部分用完了session再去关session就不会有上面的错误了
 
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance 
 
before flushing: com.gjw.entity.building.GesBuilding
通常这种状况是由于保存时从数据库中获取的游离对象中的对象不为空,可是其ID却为空。
 
Could not read entity state from ResultSet : EntityKey
是由于数据库的字段与实体的属性不匹配,好比实体中应该是manyto,而数据库中是varchar
 
hibernate查询过滤:
一个老师教许多学生,一个学生被许多老师教,一个学生有好多书,同一种书被许多同窗拥有. 
要查询教拥有书"a"的学生的老师!HQL如何写呀?如何取值? 
class teacher{ 
String id; 
String name; 
Set students; 
class student{ 
String id; 
String name; 
Set teachers; 
Set books; 
class book{ 
String id; 
String name; 
Set students; 
}
 
 
 
================================
 
这种写法(t.students)确定是能够的,你试试 
SELECT t FROM teacher t join t.students s join s.books b where b.name = 'a'
 
================================
 
SELECT t FROM teacher t where t.students.books.name = 'a'   
 
首先students.books这里,students是集合,因此这个表达式是确定不对的 
同理books.name也不对
 
================================
 
SELECT t FROM Teacher t,Student s,Book b where s.id in elements(t.students) and b.id in elements(s.books) 
这种方法没有出错!不过这种方式要用子查询!
 
================================
 
是的,element(Set)和indice(List)均可以取集合中的元素,但用在where子句的条件是须要数据库支持子查询,mysql就不行 
 
另外t.students s中s并非集合的意思,而是t的students对象的表别名,join t.students s这个hql,hibernate会翻译成两个表的内链接关
 
 
================另外一篇文章,和上面的结合就ok了================
 
 今天在作一个项目须要作到Set集的数据过虑,由于在获取一个User的时候不能将属于这个User的Knowledge所有取出,再一个一个地筛选符
 
合条件的Knowledge,这样作会在很大的程度降底系统性能。 
 
在 Hibernate中类型为Set、List的实体属性也是能够链接查询的,例如User里面有一个Set<Knowledge> knowledge属性要获取User中
 
Knowledge的isShared的属性为true的User而且在返回的User中的knowledges 中包含isShared为true的Knowledge对象的时候,就要通Set的
 
过虑查询(左链接查询),在hibernate3.2.3之后的写法如 下: 
select distinct u from User u left join fetch u.knowledges k where k.isShare=true。 
这样就只会获取knowledge的isShared为true的User,而且User里面的knowleges中包含knowledge的isShared为true的Knowlege对象。 
需 要注意的是:关键字distinct和fetch。要实现上面的数据过虑就得要这两个关键字。第一个关键字是独立的意思,第二个关键字是以一
 
条sql语句 执行。若是少了fetch这个关键字,则达不到目的。返回的结果是一个User包含isShared为true和false的knowledge集合。 
 
同理,若是Knowledge里面还要Set、List属性,而且也要据根这些属性中的对象的某些属性约束查询的话(二级或三级链接查询),也是一
 
样能够作到的。
 
object references an unsaved transient instance - save the transient instance before flushing: com.gjw.entity.area.GesArea
 
这个问题是因为保存的时候对象的id为空,可是这个对象不为空
 
query.uniqueResult(); 
关于uniqueresult的问题:
在保证只返回一行数据的时候才能使用,例如count的时候。
另外createsqlquery不能使用from entity的方式查询
 
若是<prop key="hibernate.hbm2ddl.auto">create</prop>不能生成数据库表,
  1. <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>  
相关文章
相关标签/搜索