Marcin46
Marcin46

Reputation: 120

Spring Hibernate: TypedQuery NullPointerException

I'm trying to do some api in spring mvc. When I run clearKoszyk method:

 $scope.clearKoszyk = function(){

                    var successCallBack = function(response){
                         $scope.seans = response.data;
                        };

               var errorCallBack = function(response){
                    $scope.seans = response.status;
                        };

                      $http.post('http://localhost:8080/kino/koszyk/delete').then(successCallBack, errorCallBack);

                }
            });

I get in response status 500 error so it's an internal server error. It's caused by:

SEVERE: Servlet.service() for servlet [DispatcherServlet] in context with 
path [/kino] threw exception [Request processing failed; nested exception 
is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at org.hibernate.internal.SessionFactoryImpl.getReturnTypes(SessionFactoryImpl.java:1112)
at org.hibernate.internal.AbstractQueryImpl.getReturnTypes(AbstractQueryImpl.java:192)
at org.hibernate.ejb.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:690)
at sun.reflect.GeneratedMethodAccessor69.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy43.createNamedQuery(Unknown Source)
at kino.repositoryImpl.KoszykRepositoryImpl.deleteKoszyk(KoszykRepositoryImpl.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy50.deleteKoszyk(Unknown Source)
at kino.serviceImpl.KoszykServiceImpl.deleteKoszyk(KoszykServiceImpl.java:50)
at kino.controllers.KoszykController.DeleteKoszyk(KoszykController.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

So I think this NPE is here:

at kino.repositoryImpl.KoszykRepositoryImpl.deleteKoszyk(KoszykRepositoryImpl.java:60)

But I really don't know what cause this exception. I'm checking if EntityManager or User is null.

56    public void deleteKoszyk(User user) throws NullPointerException{
57      
58      if(user != null){
59          if(emManager != null){
60               TypedQuery<Koszyk> query = emManager.createNamedQuery("Koszyk.deleteKoszyk", Koszyk.class);
            query.setParameter("id", user.getId());
            query.executeUpdate();
        }else{
            throw new NullPointerException("emManager = null");
        }
    }else{
        throw new NullPointerException("Podany użytkownik nie istnieje");
    }
 }

It's my koszyk class.

@Entity
@NamedQuery(name = "Koszyk.deleteKoszyk", query = "DELETE FROM Koszyk k WHERE k.user.id = :id")
@Table(name="Koszyk")
public class Koszyk implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name="Koszyk_id")
private Long id;
@OneToOne
private User user;
@Column(name="Cena")
private int cena;
@Column(name="KoszykItems")
@OneToMany(mappedBy="koszyk", fetch = FetchType.EAGER)
private List<KoszykItem> koszykItems;

This problem shows only when I try to delete or find koszyk by id. I can read from this entity and I can show it in a normal way. It's my KoszykRepository class:

@Repository
@Transactional
public class KoszykRepositoryImpl implements KoszykRepository {


@PersistenceContext
private EntityManager emManager;

public KoszykRepositoryImpl(){

}

@Override
public void update(Koszyk koszyk) {
    emManager.merge(koszyk);

}

@Override
public Koszyk deleteKoszykItem(KoszykItem koszykItem, User user) {

    Koszyk koszyk = read(user);
    List<KoszykItem> listaItemow = koszyk.getKoszykItems(); 
    listaItemow.remove(koszykItem);
    koszyk.setKoszykItems(listaItemow);
    update(koszyk);

    return koszyk;

}
@Override
public void deleteKoszyk(User user) throws NullPointerException{

    if(user != null){
        if(emManager != null){
            TypedQuery<Koszyk> query = emManager.createNamedQuery("Koszyk.deleteKoszyk", Koszyk.class);
            query.setParameter("id", user.getId());
            query.executeUpdate();
        }else{
            throw new NullPointerException("emManager = null");
        }
    }else{
        throw new NullPointerException("Podany użytkownik nie istnieje");
    }
}

@Override
public void create(User user, Koszyk koszykDoZapisu) {

    List<Koszyk> ListaKoszykow = read();
    boolean zapisz = true;

    if(user == null){
        throw new NullPointerException("Zaloguj się!");
    }else if(!ListaKoszykow.isEmpty() && ListaKoszykow != null){
            for(Koszyk koszyk: ListaKoszykow){
                if(koszyk.getUser().getId() == user.getId()){
                    zapisz = false;
                    break;
                }       
            }
        }

        if(zapisz){
            koszykDoZapisu.setUser(user);
            emManager.persist(koszykDoZapisu);
        }
    }   


@Override
public List<Koszyk> read() {

    return emManager.createQuery("SELECT k FROM Koszyk k", Koszyk.class).getResultList();
}

@Override
public Koszyk read(User user) {

    List<Koszyk> ListaKoszykow = read();
    Koszyk zwracany = new Koszyk();

    if(user == null){
        throw new NullPointerException("Zaloguj się!");
    }

    if(ListaKoszykow.isEmpty() || ListaKoszykow == null){
            throw new NullPointerException("Dany użytkownik nie ma jeszcze przypisanego koszyka");
        }else{
            for(Koszyk koszyk: ListaKoszykow){
                if(koszyk.getUser().equals(user)){
                    zwracany = koszyk;
                    //Hibernate.initialize(zwracany.getKoszykItems());
                }
            }
    }   

    return zwracany; 
}

}

[EDIT]

I've changed delete function to this:

 public void deleteKoszyk(User user) throws NullPointerException{

    if(user != null){
        if(emManager != null){
            final Query query = emManager.createNamedQuery("Koszyk.deleteKoszyk");
            query.setParameter("id", user.getId());
63              final int executeUpdate = query.executeUpdate();
        }else{
            throw new NullPointerException("emManager = null");
        }
    }else{
        throw new NullPointerException("Podany użytkownik nie istnieje");
    }
}

and the stacktree is completly different:

SEVERE: Servlet.service() for servlet [DispatcherServlet] in context with 
path [/kino] threw exception [Request processing failed; nested exception is 
javax.persistence.PersistenceException: 
org.hibernate.exception.ConstraintViolationException: Cannot delete or 
update a parent row: a foreign key constraint fails (`marcin`.`koszykitem`, 
CONSTRAINT `FK8F90CFF02AE8E273` FOREIGN KEY (`koszyk_Koszyk_id`) REFERENCES 
`koszyk` (`Koszyk_id`))] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
Cannot delete or update a parent row: a foreign key constraint fails 
(`marcin`.`koszykitem`, CONSTRAINT `FK8F90CFF02AE8E273` FOREIGN KEY 
(`koszyk_Koszyk_id`) REFERENCES `koszyk` (`Koszyk_id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:932)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy51.executeUpdate(Unknown Source)
at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:95)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:413)
at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:283)
at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1135)
at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.java:116)
at org.hibernate.ejb.QueryImpl.internalExecuteUpdate(QueryImpl.java:183)
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:99)
at kino.repositoryImpl.KoszykRepositoryImpl.deleteKoszyk(KoszykRepositoryImpl.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy48.deleteKoszyk(Unknown Source)
at kino.serviceImpl.KoszykServiceImpl.deleteKoszyk(KoszykServiceImpl.java:50)
at kino.controllers.KoszykController.DeleteKoszyk(KoszykController.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

Upvotes: 2

Views: 1016

Answers (1)

Kevin Peters
Kevin Peters

Reputation: 3444

It's hard to guess where the NPE is coming from without debugging it, maybe there is no User assigned to your Koszyk instance. Your @OneToOne mapping does not prevent running into null here because the default is optional = true. If you would adjust that, the constraint would help you to at least avoid that.

Much more confusing is that you do not get another type of error. I would expect something like:

... Update/delete queries cannot be typed ...

Because update / delete queries, resp. the executeUpdate() method does just return an update count int value, no instances.

You should turn it into:

final Query query = emManager.createNamedQuery("Koszyk.deleteKoszyk");
query.setParameter("id", user.getId());
final int executeUpdate = query.executeUpdate();

Update:

Since we have the real root cause now, the issue seems clear. You can't delete an entity as long as it's id is used as a foreign key on another entity. Delete the entity which references this Koszyk first.

Upvotes: 2

Related Questions