{"id":12,"date":"2006-08-04T08:33:10","date_gmt":"2006-08-04T08:33:10","guid":{"rendered":"http:\/\/euve3303.vserver.de\/stefan\/blog\/?p=9"},"modified":"2006-08-04T08:33:10","modified_gmt":"2006-08-04T08:33:10","slug":"sequences-mit-hibernate3-und-hsqldb","status":"publish","type":"post","link":"https:\/\/cogito-ergo-blog.de\/blog\/2006\/08\/04\/sequences-mit-hibernate3-und-hsqldb\/","title":{"rendered":"Sequences mit Hibernate3 und HSQLDB"},"content":{"rendered":"<p>HSQLDB unterst\u00fctzt seit einiger Zeit <em>Sequences<\/em>. Mit Sequences lassen sich sehr einfach Prim\u00e4rschl\u00fcssel generieren was\u00a0von\u00a0Hibernate mit dem Sequences-Generator auch direkt unterst\u00fctzt wird. Will man das Default-Verhalten &quot;eine Sequence f\u00fcr alle Entit\u00e4ten&quot; aber ersetzen durch &quot;eine Sequence per Entit\u00e4t&quot;, so st\u00f6\u00dft man mit\u00a0HSQLDB 1.8 und Hibernate 3.1.3 auf Probleme.<\/p>\n<p><!--more--><\/p>\n<p>Das Problem liegt an den von Hibernate erzeugten SQL Statements zum &quot;fetchen&quot; der Sequences:<\/p>\n<p \/>\n<blockquote style=\"border: 1px solid gray; font-family: courier new; font-size: 85%; background-color: rgb(238, 238, 238); white-space: pre; overflow: auto;\"><p><font size=\"2\">select next value for hibernate_sequence from dual_hibernate_sequence<\/font><\/p><\/blockquote>\n<p \/>\n<p>Zum einen ist eine solche Tabelle in der Standardinstallation gar nicht vorhanden, zum anderen h\u00e4ngt der Name der &quot;Fetch&quot;-Tabelle vom Namen der Sequence ab.<\/p>\n<p>Man w\u00fcrde also pro Entit\u00e4t einen &quot;Fetch&quot;-Table brauchen.<\/p>\n<p>Abhilfe schafft eine kleine Erweiterung des HSQLDialects von Hibernate 3.1:<\/p>\n<p \/>\n<blockquote style=\"border: 1px solid gray; font-family: courier new; font-size: 85%; background-color: rgb(238, 238, 238); overflow: auto; height: 200px;\"><p>\n<tt class=\"java\"><span class=\"java4\">package <\/span><span class=\"java10\">com.rinke.solutions.hibernate;<\/p>\n<p><\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.hibernate.dialect.HSQLDialect;<\/p>\n<p><\/span><span class=\"java4\">public class <\/span><span class=\"java10\">MyHSQLDialect <\/span><span class=\"java4\">extends <\/span><span class=\"java10\">HSQLDialect <\/span><span class=\"java8\">{<\/p>\n<p>&#xA0;&#xA0;&#xA0; <\/span><span class=\"java16\">@Override<br \/>\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java10\">String getSequenceNextValString<\/span><span class=\"java8\">(<\/span><span class=\"java10\">String sequenceName<\/span><span class=\"java8\">) {<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">return <\/span><span class=\"java5\">&#34;select next value for &#34; <\/span><span class=\"java10\">+ sequenceName<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; + <\/span><span class=\"java5\">&#34; from hsql_dual&#34;<\/span><span class=\"java10\">;<br \/>\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}<br \/>\n} <\/span><\/tt><\/p><\/blockquote>\n<p \/>\n<p>Damit werden nun alle Seqences von einem Table gefetched. Dieser eine Table muss nun nat\u00fcrlich noch angelegt werden. Wie er konkret aussieht ist eigentlich egal, Hauptsache ein besitzt nur eine Zeile, damit das Select-Statement auch genau nur einen &quot;Next Value&quot; zur\u00fcck liefert:<\/p>\n<p \/>\n<blockquote style=\"border: 1px solid gray; font-family: courier new; font-size: 85%; background-color: rgb(238, 238, 238); white-space: pre; overflow: auto;\"><p><font face=\"courier new,courier,monospace\" size=\"2\">create table hsql_dual ( id integer );<\/font><\/p>\n<p><font face=\"courier new,courier,monospace\" size=\"2\">insert into hsql_dual values ( 1 );<\/font>\u00a0<\/p><\/blockquote>\n<p \/>\n<p>Die Verwendung von einer Sequence per Entit\u00e4t erreicht man am einfachsten mit einem eigenen Identity-Generator. Statt &quot;sequence&quot; schreiben wir auf hier unsere eigene Klasse:<\/p>\n<p \/>\n<blockquote style=\"border: 1px solid gray; font-family: courier new; font-size: 85%; background-color: rgb(238, 238, 238); overflow: auto; height: 200px;\"><p>\n<tt class=\"java\"><span class=\"java4\">package <\/span><span class=\"java10\">com.rinke.solutions.hibernate;<\/p>\n<p><\/span><span class=\"java4\">import <\/span><span class=\"java10\">java.util.Properties;<\/p>\n<p><\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.hibernate.MappingException;<br \/>\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.hibernate.dialect.Dialect;<br \/>\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.hibernate.id.PersistentIdentifierGenerator;<br \/>\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.hibernate.id.SequenceGenerator;<br \/>\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.hibernate.type.Type;<\/p>\n<p><\/span><span class=\"java4\">public class <\/span><span class=\"java10\">TableNameSequenceGenerator&#xA0; <\/span><span class=\"java4\">extends <\/span><span class=\"java10\">SequenceGenerator <\/span><span class=\"java8\">{<\/p>\n<p>&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0; * If the parameters do not contain a <\/span><span class=\"java13\">{@link SequenceGenerator#SEQUENCE} <\/span><span class=\"java14\">name, we<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0; * assign one based on the table name.<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0; *\/<br \/>\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java16\">@Override<br \/>\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java9\">void <\/span><span class=\"java10\">configure<\/span><span class=\"java8\">(<\/span><span class=\"java10\">Type type, Properties params, Dialect dialect<\/span><span class=\"java8\">) <\/span><span class=\"java4\">throws <\/span><span class=\"java10\">MappingException <\/span><span class=\"java8\">{<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">if<\/span><span class=\"java8\">(<\/span><span class=\"java10\">params.getProperty<\/span><span class=\"java8\">(<\/span><span class=\"java10\">SEQUENCE<\/span><span class=\"java8\">) <\/span><span class=\"java10\">== <\/span><span class=\"java4\">null <\/span><span class=\"java10\">|| params.getProperty<\/span><span class=\"java8\">(<\/span><span class=\"java10\">SEQUENCE<\/span><span class=\"java8\">)<\/span><span class=\"java10\">.length<\/span><span class=\"java8\">() <\/span><span class=\"java10\">== <\/span><span class=\"java7\">0<\/span><span class=\"java8\">) {<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java10\">String tableName = params.getProperty<\/span><span class=\"java8\">(<\/span><span class=\"java10\">PersistentIdentifierGenerator.TABLE<\/span><span class=\"java8\">)<\/span><span class=\"java10\">;<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">if<\/span><span class=\"java8\">(<\/span><span class=\"java10\">tableName != <\/span><span class=\"java4\">null<\/span><span class=\"java8\">) {<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java10\">String seqName = <\/span><span class=\"java5\">&#34;seq_&#34; <\/span><span class=\"java10\">+ tableName;<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; params.setProperty<\/span><span class=\"java8\">(<\/span><span class=\"java10\">SEQUENCE, seqName<\/span><span class=\"java8\">)<\/span><span class=\"java10\">;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; }<br \/>\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">super<\/span><span class=\"java10\">.configure<\/span><span class=\"java8\">(<\/span><span class=\"java10\">type, params, dialect<\/span><span class=\"java8\">)<\/span><span class=\"java10\">;<br \/>\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}<br \/>\n}<\/span><\/tt>\n<\/p><\/blockquote>\n<p \/>\n<p>Ein komplettes Beispiel (verwendet zus\u00e4tzlich Spring aber nur der Einfachheit wegen) kann <a href=\"http:\/\/www.lookingeye.de\/downloads\/hibernateHSQL.zip\">hier<\/a> heruntergeladen werden.<\/p>\n<p>Referenzen: CustomSequences mit Hibernate: <a href=\"http:\/\/www.hibernate.org\/296.html\">http:\/\/www.hibernate.org\/296.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>HSQLDB unterst\u00fctzt seit einiger Zeit Sequences. Mit Sequences lassen sich sehr einfach Prim\u00e4rschl\u00fcssel generieren was\u00a0von\u00a0Hibernate mit dem Sequences-Generator auch direkt unterst\u00fctzt wird. Will man das Default-Verhalten &quot;eine Sequence f\u00fcr alle Entit\u00e4ten&quot; aber ersetzen durch &quot;eine Sequence per Entit\u00e4t&quot;, so st\u00f6\u00dft &hellip; <a href=\"https:\/\/cogito-ergo-blog.de\/blog\/2006\/08\/04\/sequences-mit-hibernate3-und-hsqldb\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/12"}],"collection":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":0,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/12\/revisions"}],"wp:attachment":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}