您的位置:首页 > 产品设计 > UI/UE

初学Hibernate,让人抓狂

2011-07-27 23:09 162 查看
Hibernate是个强大,开发效率高的开源框架—这已是行业所公认的事实.
对于初接触Hibernate的我来说,却因为他强大的封装能力,出现问题时,完成不知从何处下手.
信手写了个Person类:package com.wls.domain; import java.util.Date; public class Person {    private Integer personId;    private String name;    private Date birthday;    private Address address;        public Person(){            }     public Integer getPersonId() {        return personId;    }     public void setPersonId(Integer personId) {        this.personId = personId;    }     public String getName() {        return name;    }     public void setName(String name) {        this.name = name;    }     public Date getBirthday() {        return birthday;    }     public void setBirthday(Date birthday) {        this.birthday = birthday;    }     public Address getAddress() {        return address;    }     public void setAddress(Address address) {        this.address = address;    }     @Override    public String toString() {        return "Person [personId=" + personId + ", name=" + name                + ", birthday=" + birthday + ", address=" + address + "]";    }        }
再写一个Address类:package com.wls.domain; import java.util.Datepublic class Address {    private Integer addressId;    private String addressDetail;        private Person person;            public Address(){            }        public Address(String addressDetail){        this.addressDetail=addressDetail;    }     public Integer getAddressId() {        return addressId;    }     public void setAddressId(Integer addressId) {        this.addressId = addressId;    }     public String getAddressDetail() {        return addressDetail;    }     public void setAddressDetail(String addressDetail) {        this.addressDetail = addressDetail;    }     public Person getPerson() {        return person;    }     public void setPerson(Person person) {        this.person = person;    }     @Override    public String toString() {        return "Address [addressId=" + addressId + ", addressDetail="                + addressDetail +"]";    }}
这个两Pojo对应的映射文件为:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.wls.domain">    <class name="Person">        <id name="personId" type="java.lang.Integer">            <generator class="native"></generator>        </id>        <property name="name" type="java.lang.String"></property>        <property name="birthday" type="java.util.Date"></property>        <one-to-one name="address" class="Address" property-ref="addressId" cascade="save-update" >        </one-to-one>    </class>        <class name="Address">        <id name="addressId" type="java.lang.Integer">            <generator class="native"></generator>        </id>        <property name="addressDetail" type="java.lang.String"></property>        <many-to-one name="person" class="Person"  unique="true" not-null="true"></many-to-one>    </class>
</hibernate-mapping>
前奏写好了,之后写了个DAO--UserManagerDao:package com.wls.dao; import java.util.ArrayList;import[/b] java.util.List; import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction; import com.wls.domain.Address;import com.wls.domain.Person; public class UserManagerDao {    private SessionFactory sessionFactory;    private Session session;            public void setSessionFactory(SessionFactory sessionFactory) {        this.sessionFactory = sessionFactory;    }    public Session getSession() {                if(session==null){            session=sessionFactory.openSession();        }        return session;    }        public Integer addAddress(Address address){        Transaction tx=getSession().beginTransaction();        Integer AddressId=(Integer)getSession().save(address);        tx.commit();        return AddressId;    }        public Integer addPerson(Person person){        Transaction tx=getSession().beginTransaction();        Integer personId=(Integer)getSession().save(person);        tx.commit();        return personId;    }        public Person getPerson(Integer personId){        Transaction tx=getSession().beginTransaction();        Person person=(Person) getSession().get(Person.class, personId);        tx.commit();        return person;    }        public List<Person> getAllPerons(){        Transaction tx=getSession().beginTransaction();        Query query=getSession().createQuery("select person from Person person");        if(query==null){            System.out.println("query is null");            return new ArrayList<Person>();        }else{            System.out.println("query is not null");        }        List<Person> persons=query.list();        tx.commit();        return persons;    }        public List<Address> getAllAddresses(){        Transaction tx=getSession().beginTransaction();        Query query=getSession().createQuery("select person from Address person");        if(query==null){            System.out.println("query is null");            return new ArrayList<Address>();        }else{            System.out.println("query is not null");        }        List<Address> addresses=query.list();        tx.commit();        return addresses;    }        }
 
最后,就只差用于测试的类了—MainTest:package com.wls.test; import java.util.Date;import java.util.List; import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wls.dao.UserManagerDao;import com.wls.domain.Address;import com.wls.domain.Person; public class MainTest {    public static void main(String[] args){        System.out.println("Main Method!");                ApplicationContext context=new ClassPathXmlApplicationContext("SpringConfig.xml");        UserManagerDao userManagerDao=context.getBean("userManagerDao", UserManagerDao.class);                Address address=new Address("广东广州");                Person person=new Person();                person.setBirthday(new Date());        person.setName("佢顺");                address.setPerson(person);                userManagerDao.addAddress(address);        System.out.println("Main Mehtod End!");    }}
随手点了下运行按钮,却出现了如下错误:Hibernate: select hibernate_sequence.nextval from dualException in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.wls.domain.Person    at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243)    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456)    at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:265)    at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:275)    at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:295)    at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3403)    at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:520)    at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:230)    at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:154)    at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)    at com.wls.dao.UserManagerDao.addAddress(UserManagerDao.java:33)
    at com.wls.test.MainTest.main(MainTest.java:33)
 
再次确认映射文件,我已经写了cascade=save-update为什么会出现如此问题?
思考了半个小时,头疼,放弃了.
然后改了一下MainTest:package com.wls.test; import java.util.Date;import java.util.List; import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wls.dao.UserManagerDao;import com.wls.domain.Address;import com.wls.domain.Person; public class MainTest {    public static void main(String[] args){        System.out.println("Main Method!");                ApplicationContext context=new ClassPathXmlApplicationContext("SpringConfig.xml");        UserManagerDao userManagerDao=context.getBean("userManagerDao", UserManagerDao.class);        Address address=new Address("广东广州");        Person person=new Person();        person.setBirthday(new Date());        person.setName("佢顺");        Integer personId=userManagerDao.addPerson(person);        address.setPerson(person);        userManagerDao.addAddress(address);        List<Address> addresses=userManagerDao.getAllAddresses();                for(Address a:addresses){            System.out.println(a);        }                System.out.println("Main Mehtod End!");    }}
运行结果如春风吹过,舒畅的感觉:Hibernate: select hibernate_sequence.nextval from dualHibernate: insert into Person (name, birthday, personId) values (?, ?, ?)Hibernate: select hibernate_sequence.nextval from dualHibernate: insert into Address (addressDetail, person, addressId) values (?, ?, ?)query is not nullHibernate: select address0_.addressId as addressId1_, address0_.addressDetail as addressD2_1_, address0_.person as person1_ from Address address0_Address [addressId=42, addressDetail=广东广州]Address [addressId=44, addressDetail=广东广州]Address [addressId=46, addressDetail=广东广州]Address [addressId=48, addressDetail=广东广州]Address [addressId=50, addressDetail=广东广州]Address [addressId=52, addressDetail=广东广州]Address [addressId=55, addressDetail=广东广州]Main Mehtod End!
 
 
再改MainTest:package com.wls.test; import java.util.Date;import java.util.List; import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wls.dao.UserManagerDao;import com.wls.domain.Address;import com.wls.domain.Person; public class MainTest {    public static void main(String[] args){        System.out.println("Main Method!");                ApplicationContext context=new ClassPathXmlApplicationContext("SpringConfig.xml");        UserManagerDao userManagerDao=context.getBean("userManagerDao", UserManagerDao.class);                Address address=new Address("广东广州");                Person person=new Person();                person.setBirthday(new Date());        person.setName("佢顺");                Integer personId=userManagerDao.addPerson(person);        address.setPerson(person);                userManagerDao.addAddress(address);            List<Person> persons=userManagerDao.getAllPerons();                for(Person p:persons){            System.out.println(p);        }                System.out.println("Main Mehtod End!");    }}
 
想不到冬天来得这么快:Exception in thread "main" java.lang.NullPointerException    at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:1791)    at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:681)    at org.hibernate.type.EntityType.resolve(EntityType.java:441)    at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)    at org.hibernate.loader.Loader.doQuery(Loader.java:857)    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)    at org.hibernate.loader.Loader.doList(Loader.java:2533)    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)    at org.hibernate.loader.Loader.list(Loader.java:2271)    at org.hibernate.loader.hql.QueryLoader.list(
91ff
QueryLoader.java:452)    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)    at com.wls.dao.UserManagerDao.getAllPerons(UserManagerDao.java:60)    at com.wls.test.MainTest.main(MainTest.java:35)
想了半天,还是不明白为什么是java.lang.NullPointerException想经过测试, com.wls.dao.UserManagerDao.getAllPerons(UserManagerDao.java:60)中的query并不是null.看来问题是出在Peson对象上面了.
那是不是说我不用Address的话永远就取不了Peson了.
解决方案在哪里,又是仰望星空半天.
嗯,解决方案不在今天.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息