0

I have a pretty complicated method addOrder() which contains several queries in one transaction, and one session:

simplistically without business logic it's look like this:

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();
                     }
                 }
      } 

Dao

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);
            }
    }

while executing method addOrder() I'm getting NullPointerExeption in

updateCustomerForOrder(), Debug mode shows that session and customer objects that passed in this method are not null, so I'm a bit confused whats wrong? full stacktrace:

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());

    }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
ketchyn
  • 504
  • 3
  • 6
  • 16
  • 1
    Mostly possible that your `Item` class has wrong implementation of `hashCode()` method. Can you show its code? – Andremoniy May 19 '16 at 21:05
  • What happens if you remove the flush/clear for a test? Is the transaction too big then? I've not had to do this and it seems that you're taking over for the management that Hibernate would be doing. – stdunbar May 19 '16 at 21:25
  • The Null pointer is coming on the extractHashCode on the entity. in your case entity is Item class. Can you put the implementation details of the item class along with how hashcode method is overloaded ? – Yogesh A Sakurikar May 19 '16 at 21:31
  • post has been updated – ketchyn May 20 '16 at 08:23
  • Sorry, how did you figure out that wrong hash code relate to Items class? Exception occurres when update CustomerforOrder executes with Customer object as input parameter, and I don't see any reference on items in stack trace) – ketchyn May 20 '16 at 08:49

1 Answers1

0

this post helped https://stackoverflow.com/a/8576809/5526080

I need to add to customer updated items, not origin

 dao.updateItems(itemsToUpdate);

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

otherwise the items hash codes are different, as I understood

Community
  • 1
  • 1
ketchyn
  • 504
  • 3
  • 6
  • 16