Eine Sequenz per JPA abzufragen ist bekanntermaßen nicht so einfach – JPA 1.0 unterstützt nur Sequenzen bei der Genierung von IDs (@Id, @GeneratedValue). Eine Möglichkeit einen eindeutigen Wert trotzdem aus einer Sequenz zu bekommen ist natürlich per JPA Native Query (siehe bspw. http://stackoverflow.com/questions/277630/hibernate-jpa-sequence-non-id )
Nach kurzem googlen bekommt hier jede Menge Treffer die etwa wie folgt aussehen (für eine Oracle Sequenz):
Query query = em.createNativeQuery("select seq.nextval from dual ");
long nextNumber = new Long(((Number) query.getSingleResult()).longValue());
Leider funktioniert dies nicht (zumindest bei mir… L )
Es kommt hier immer die Fehlermeldung: ORA-00287: Sequence-Nummer hier nicht zulässig
Der Grund hierfür liegt daran, dass Hibernate (JPA unter JBoss), aus dem getSingleResult folgendes Statement baut:
select * from ( select profilenumber.nextval from dual ) where rownum <= 1
Und dies ist leider kein korrektes SQL Statement, da hier eine Sequenz in der WHERE Klausel vorkommt…
Mit folgendem Java Code erhält man das gewünschte Ergebnis:
Query query = em.createNativeQuery("select seq.nextval from dual ");
long nextNumber = Long.valueOf(query.getResultList().get(0).toString());
Hier wird die überflüssige Select-Klammer um die eigentliche Sequenzabfrage in SQL weggelassen.
Methode zur NextVal from SEQ funktioniert nicht...
AntwortenLöschenException in thread "main" java.lang.NumberFormatException: For input string: "[220120327]"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:403)
at java.lang.Long.parseLong(Long.java:461)
at com.becker.struts.database.PersistenceManager.nextAccountNumber(PersistenceManager.java:69)
at com.becker.struts.account.AccountHandler.createAccount(AccountHandler.java:28)
at com.becker.struts.database.Test.main(Test.java:17)
select seq.nextval from dual
AntwortenLöschenseq ist natürlich der Sequenz Name.
Die Sequenz muss hier natürlich manuell in Oracle angelegt werden. Die Funktionsweise des Statements kann relativ einfach bspw. mit PL/SQL Developer oder einfach auf der Konsole mit sqlplus geprüft werden.
Hallo,
AntwortenLöschenIch danke dir! Hat super funktioniert. Das "getSingleResulT()" hat mich schon wahnsinnig gemacht :D
Greetz
Q