2016-06-24 6 views
0

Ich versuche, eine gespeicherte Prozedur, deren Unterschrift aufrufen sieht wie folgt aus:`Type kann nicht null` Ausnahme sein, wenn Stored Procedure mit Spring Data JPA zu laufen versuchen

CREATE OR REPLACE PROCEDURE FIND_FIRST_BOOKMARK_GT(bookmark IN NUMBER, cur OUT SYS_REFCURSOR) 

Ich bin mit Spring-Data JPA und habe eine Anzahl verschiedener Varianten ausprobiert, aber alle folgen mehr oder weniger dem folgenden Muster. Meine Entitätsmodell eingerichtet wie folgt:

@NamedStoredProcedureQuery(name = "Response.findFirstBookmarkGreaterThan", procedureName = "FIND_FIRST_BOOKMARK_GT", 
    resultClasses = Response.class, 
    parameters = { 
     @StoredProcedureParameter(name = "bookmark", mode = ParameterMode.IN, type = Long.class), 
     @StoredProcedureParameter(name = "cur", mode = ParameterMode.REF_CURSOR, type = void.class) 
    }) 
}) 

Dann habe ich mein Repository, das wie folgt aussieht:

@Repository 
public interface ResponseRepository extends CrudRepository<Response, Long>{ 
    @Procedure("Response.findFirstBookmarkGreaterThan") 
    Response findFirstBookmarkGreaterThan(@Param("bookmark") Long bookmark); 
} 

Ich habe die Anweisungen von ganz wenigen Beispielen gefolgt, aber ich bin immer links mit der gleiche Fehler, nämlich:

java.lang.IllegalArgumentException: Type cannot be null 
at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.setHibernateType(AbstractParameterRegistrationImpl.java:182) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.<init>(AbstractParameterRegistrationImpl.java:131) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.<init>(AbstractParameterRegistrationImpl.java:140) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.<init>(AbstractParameterRegistrationImpl.java:97) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.procedure.internal.NamedParameterRegistration.<init>(NamedParameterRegistration.java:41) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.procedure.internal.ProcedureCallImpl.registerParameter(ProcedureCallImpl.java:344) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.jpa.internal.StoredProcedureQueryImpl.registerStoredProcedureParameter(StoredProcedureQueryImpl.java:152) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.newAdhocStoredProcedureQuery(StoredProcedureJpaQuery.java:175) ~[spring-data-jpa-1.9.4.RELEASE.jar:na] 
at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.createStoredProcedure(StoredProcedureJpaQuery.java:130) ~[spring-data-jpa-1.9.4.RELEASE.jar:na] 
at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.doCreateQuery(StoredProcedureJpaQuery.java:89) ~[spring-data-jpa-1.9.4.RELEASE.jar:na] 
at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.createQuery(StoredProcedureJpaQuery.java:80) ~[spring-data-jpa-1.9.4.RELEASE.jar:na] 
...... 

Irgendwelche Ideen, was hier falsch ist?

+0

Können Sie den Code ohne die Köter Parameter Referenz Erklärung versuchen und prüfen, ob der Fehler noch vorhanden – Mudassar

+0

Gleiches Problem tritt auf – mike

Antwort

0

Ich konnte diese Syntax nicht als solche arbeiten, jedoch ist der Begriff des Abrufens von einer gespeicherten Prozedur tatsächlich eine Abkürzung für die Auswahl aus (möglicherweise eine Ansicht) gemischt mit der Anwendung einiger Input-basierter Funktion. Zu diesem Zweck habe ich meine gespeicherte Prozedur durch eine Funktion/Tabelle ersetzt, die den gleichen Effekt liefert.

@Query("SELECT r FROM RESPONSES r WHERE BOOKMARK = FIND_FIRST_BOOKMARK_GT(:bookmark)") 
Response findFirstBookmarkGreaterThan(@Param("bookmark") Long bookmark); 

Dies verwendet die @Query Syntax in Verbindung mit einem Tisch und einer Funktion, deren Gesamtlogik ist identisch die gespeicherte Prozedur aufrufen I beabsichtigt hatte. Obwohl vielleicht etwas schwieriger zu folgen, ist die Syntax zumindest viel kürzer als die Verwendung der @NamedStoredProcedureQuery.

Die Funktion macht das gleiche, was die gespeicherte Prozedur ursprünglich tat, außer für den letzten Teil, der eine SELECT INTO war, ist dies jetzt als Teil der @Query gekapselt.

0

Konfrontiert mit dem gleichen Problem mit @Procedure. Als Workaround können Sie auf den EntityManager in der Serviceklasse und der Aufrufprozedur verweisen.

@Service 
public interface ResponseService { 

    @PersistenceContext 
    EntityManager entityManager; 

    public Response findFirstBookmarkGreaterThan(Long bookmark){ 
      Query query = entityManager.createNamedStoredProcedureQuery("Response.findFirstBookmarkGreaterThan"); 
      query.setParameter("bookmark", bookmark); 
      return query.getFirstResult(); 
    }; 
} 

Beachten Sie, dass Antwort ein @Entity sein muss.

0

Mit nativer Abfrage können wir auch Speicherprozedur aufrufen. Wenn Sie mit MySQL dann die Systex folgenden ist:

@Query(nativeQuery = true,value = "call getEmployeeList") 
List<Employee> getEmployeeList();