Hibernate,一个事务中的几个查询 - NullPointerException

时间:2016-05-19 20:56:44

标签: java hibernate

我有一个非常复杂的方法addOrder(),它在一个事务中包含多个查询,还有一个会话:

简单地没有业务逻辑,它看起来像这样:

DBservice

     public boolean addOrder( List<Items> item, String custumerName, double sum){
       try{
          session = sesinfactory.openSession();
           tx = session.beginTransaction();
        ....

          Dao dao = new Dao(session);
          Custumer custumer = dao.getCustomerByName(custumerName);
          List<Items> tocheckItems = dao.getItems(item);
        ...
           dao.updateItems(itemsToUpdate);

            if (custumer != null) {
                 if (custumer.getCoins() >= sum) {
                       for (Items items : item) {
                            custumer.addItem(items);
                       }
                 }
             } 
          dao.updateCustomerForOrder(custumer);
          tx.commit();
      }
        .....
        finally {
                    if (session != null){
                        session.close();
                     }
                 }
      } 

public class Dao {
    private Session session;
    public Dao(Session session) {
        this.session = session;
    }


          public void  updateItems(List<Items> itemsName) {
                int i=0;
                for (Items s : itemsName) {

                    session.update(s);
                    if( i % 50 == 0 ) { // Same as the JDBC batch size
                        //flush a batch of inserts and release memory:
                        session.flush();
                        session.clear();
                    }
                    i++;
                }

            }

          public void updateCustomerForOrder(Custumer custumer) {
                session.update(custumer);
            }
    }

执行方法addOrder()我在

中获取NullPointerExeption

updateCustomerForOrder(),调试模式显示传入此方法的sessioncustomer个对象 不是空的,所以我有点困惑什么是错的? 完整的堆栈跟踪:

java.lang.NullPointerException
    at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.extractHashCode(AbstractTypeDescriptor.java:84)
    at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:216)
    at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:220)
    at org.hibernate.type.EntityType.getHashCode(EntityType.java:391)
    at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:258)
    at org.hibernate.engine.spi.EntityKey.generateHashCode(EntityKey.java:76)
    at org.hibernate.engine.spi.EntityKey.<init>(EntityKey.java:71)
    at org.hibernate.internal.AbstractSessionImpl.generateEntityKey(AbstractSessionImpl.java:327)
    at org.hibernate.engine.internal.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:311)
    at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:255)
    at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:521)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:100)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676)
    at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:235)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:86)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:375)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:349)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244)
    at org.hibernate.event.internal.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireUpdate(SessionImpl.java:739)
    at org.hibernate.internal.SessionImpl.update(SessionImpl.java:731)
    at org.hibernate.internal.SessionImpl.update(SessionImpl.java:726)
    at org.CoinsShop.DataBase.Dao.updateCustomerForOrder(Dao.java:129)
    at org.CoinsShop.DataBase.DbService.addOrder(DbService.java:286)
    at org.CoinsShop.bussinessLayer.BusineesLayer.handleOrder(BusineesLayer.java:61)
    at org.CoinsShop.bussinessLayer.BusineesLayer$handleOrder.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
    at org.CoinsShop.DataBase.DbServiceTest.addOrder2Test(DbServiceTest.groovy:337)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

UPD。

@Entity
@Table(name="Items")
public class Items implements  Serializable,Comparable<Items>  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column(name="id")
    private Long id;
    @Column(name="name", unique = true)
    private String name;
    @Column(name="price")
    private double price;
    @Column(name="count")
    private int count;

    @OneToMany(fetch = FetchType.EAGER,mappedBy = "item", cascade = CascadeType.ALL,orphanRemoval = true)
    List<Order> orders = new LinkedList<Order>();

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Items items = (Items) o;

        return name.equals(items.name);

    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        result = id != null ? id.hashCode() : 0;
        result = 31 * result + name.hashCode();
        temp = Double.doubleToLongBits(price);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        result = 31 * result + count;
        result = 31 * result + (orders != null ? orders.hashCode() : 0);
        return result;
    }

    @Override
    public int compareTo(Items o) {
        return getName().compareTo(o.getName());

    }
}

1 个答案:

答案 0 :(得分:0)

这篇文章帮助https://stackoverflow.com/a/8576809/5526080

我需要添加到客户更新的项目,而不是原点

 dao.updateItems(itemsToUpdate);

            if (custumer != null) {
                 if (custumer.getCoins() >= sum) {
                       for (Items items : itemsToUpdate) {
                            custumer.addItem(itemsToUpdate);
                       }
                 }
             } 
          dao.updateCustomerForOrder(custumer);
          tx.commit();

否则项目哈希码是不同的,正如我所理解的那样