Kaskadierende Tabellen, die autoinkrementierte Primärschlüssel enthalten, wurden nicht ordnungsgemäß gespeichert, da Tabellen nicht in der richtigen Reihenfolge in der Speicherwarteschlange verarbeitet wurden.
Eine Tabelle (A) hat einen zugewiesenen Primärschlüssel. Eine zweite Tabelle (B) ist mit Tabelle A verknüpft, die Kaskadierung ist aktiviert, und es wird ein autoinkrementierter Primärschlüssel verwendet. Beim Versuch Tabelle B zu speichern stellt Hibernate fest, dass Tabelle A zuerst gespeichert werden sollte und fügt diese der Speicherwarteschlange hinzu. Hibernate versucht dann sofort Tabelle B zu speichern. Dieser Speichervorgang schlägt fehl, da Tabelle B eine Primärschlüsselreferenz von Tabelle A benötigt, die jedoch Null ist, während sich diese in der Speicherwarteschlange befindet.
Um dieses Problem zu umgehen, deaktivieren Sie die Tabellenkaskadierung und stellen Sie sicher, dass die Tabelle mit dem zugewiesenen Primärschlüssel gespeichert wird, ehe Sie versuchen eine Tabelle mit autoinkrementiertem Primärschlüssel zu speichern.
Wenn eine refresh()-Methode sofort vor einem insert() aufgerufen wird und das Caching der zweiten Ebene aktiviert ist, so wird die Entity ins Cache der zweiten Ebene eingefügt. Wird refresh() jedoch nicht erfolgreich festgeschrieben, so werden die gecachten Daten nicht automatisch geräumt. Dies geschieht, weil refresh() den Entity-Status nicht verfolgt. Da der refresh()-Vorgang in der Regel für generierte Properties verwendet wird, besteht eine Problemumgehung in diesem Fall in der Verwendung der @Generated-Annotation. Sie können das Problem auch umgehen, indem Sie den Cache-Eintrag manuell räumen.
Diese Art von Änderung führt dazu, dass der org.hibernate.test.hql.ASTParserLoadingTest-Test und der org.hibernate.test.stateless.StatelessSessionTest-Test fehlschlagen. Um das Problem zu umgehen, definieren Sie einen neuen Dialekt:
public class SQLServer2008Dialect extends SQLServerDialect
{
public SQLServer2008Dialect()
{
registerColumnType( Types.DATE, "date" );
registerColumnType( Types.TIME, "time" );
registerColumnType( Types.TIMESTAMP, "datetime2" );
registerFunction( "current_timestamp",
new NoArgSQLFunction("current_timestamp",
Hibernate.TIMESTAMP,false) );
}
}
public class SQLServer2008Dialect extends SQLServerDialect
{
public SQLServer2008Dialect()
{
registerColumnType( Types.DATE, "date" );
registerColumnType( Types.TIME, "time" );
registerColumnType( Types.TIMESTAMP, "datetime2" );
registerFunction( "current_timestamp",
new NoArgSQLFunction("current_timestamp",
Hibernate.TIMESTAMP,false) );
}
}
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Wurde ein Einfügungsvorgang mittels jconn3.jar ausgeführt, so wurden Null-Bit-Werte zu 0 konvertiert, damit keine Ausnahme gemeldet wurde. Sybase gestattet keinen Nullwert für den Bit-Datentyp, so dass Null-Bit-Werte zu Ausnahmen führen.
Um dieses Problem in Hibernate zu umgehen und den Wert wie beabsichtigt als Null zu persistieren, mappen Sie den Typ zu org.hibernate.test.where.NumericTrueFalseType statt boolean:
Ein Fehler in jConnect bedeutet, dass die FetchingScrollableResultsImpl.isResultSetEmpty()-Methode folgendes wiedergibt, um zu bestimmen, ob ResultSet leer ist:
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Ist das ResultSet leer, so sollte FetchingScrollableResultsImpl.isResultSetEmpty() "false" wiedergeben, Sybase JDBC jedoch "true". Dieses Problem lässt sich derzeit noch nicht umgehen.
Wenn Hibernate eine cachebare Anfrage unter Verwendung eines ResultTransformer ausführt, so versucht es die Ergebnisse nach Anwendung des ResultTransformer zu cachen. Die Daten können jedoch verändert sein, so dass Hibernate sie nicht lesen kann. In diesem Fall wird eine ClassCastException beim Versuch die Ergebnisse zu cachen gemeldet.
Von Oracle 11g R2 (RAC) hat sich das Verhalten der CREATE TABLE Anweisung dahingehend geändert, als dass beim Erstellen einer konventionellen Tabelle in einer mit den Standardoptionen erstellten Datenbank das erste Segment nicht erstellt wird, ehe nicht die erste Reihe in die Tabelle eingefügt wurde (siehe http://download.oracle.com/docs/cd/E11882_01/server.112/e10595/tables002.htm#ADMIN13319 für Einzelheiten).
Als Folge dieser Änderung starten bei der ID-Generatorklasse sequence-identity als Standard erstellte Sequenzen mit 2 oder 4 statt mit 1. Zur Umgehung dieses Problems:
Verwenden Sie eine andere ID-Generator Klasse oder
Deaktivieren Sie die verschobene Segmenterstellung in Oracle durch Einstellung des Initialisierungsparameters DEFERRED_SEGMENT_CREATION auf FALSE. Die CREATE TABLE Anweisung hat zwei neue Klauseln (SEGMENT CREATION DEFERRED und SEGMENT CREATION IMMEDIATE), die den Wert des DEFERRED_SEGMENT_CREATION-Parameters außer Kraft setzen.
In Oracle 11g R2 (sowohl RAC als auch Standalone) kann eine komplexe Anfrage mit LockMode.UPGRADE (d.h. "for update") einen "No more data to read from socket"-Fehler verursachen. Dies ist kein Hibernate-Bug, sondern hat mit der Datenbankkonfiguration zu tun. Weitere Informationen finden Sie unter Bug Hunting. Sie umgehen das Problem, indem Sie LockMode.UPGRADE bei solchen Anfragen vermeiden.
Hibernate protokolliert derzeit nicht die Ausführungszeit jeder Anfrage. Dies wird sich wahrscheinlich in zukünftigen Versionen der JBoss Enterprise Application Platform ändern.
Dies ist ein Problem mit cglib, welches in dieser Release der JBoss Enterprise Application Platform veraltet ist. Weitere Einzelheiten finden Sie unter http://sourceforge.net/tracker/index.php?func=detail&aid=2796998&group_id=56933&atid=482368. cglib entfernt Feldannotationen bei der Transformation einer Klasse mit TransformingClassGenerator wegen eines Problems mit der visitField-Methode. Sie können dieses Problem umgehen, indem Sie "Getter" statt Felder annotieren, allerdings ist dies eventuell nicht für schwere Applikationen möglich, die zu JBoss Enterprise Application Platform 5 portiert werden.
Hibernate unterstützt derzeit keine Tuple-Syntax in HQL oder Criteria in Datenbanken, die Tuple-Syntax nicht unterstützen. Wenn eine Datenbank zum Beispiel Tuple-Syntax nicht unterstützt:
wo (a,b) in ( (1,2), (3,4) )
wo (a,b) in ( (1,2), (3,4) )
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Sollte Hibernate übersetzen:
wo ( (a=1 UND b=2) ODER ( (a=3 UND b=4) )
wo ( (a=1 UND b=2) ODER ( (a=3 UND b=4) )
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Derzeit gibt es keine Möglichkeit, dieses Problem zu umgehen, außer diese Syntaxanfrage bei Datenbanken, die die Tuple-Syntax nicht unterstützen, zu vermeiden.
Wird ein für die Datenbank reservierter Schlüssel als Property-Name mit einer Hibernate Validator Annotation verwendet (zum Beispiel @Min oder @Max), so werden Ausnahmen in SchemaExport gemeldet, selbst wenn Sie einen Spaltennamen festlegen. Der Grund hierfür ist, dass Hibernate den festgelegten Namen ignoriert. Sie umgehen das Problem, indem Sie den Property-Namen an etwas mappen, das kein für die Datenbank reservierter Schlüssel mit der @Column-Annotation ist. Die Behebung des Problems wird in Hibernate 4 erwartet.
Der QueryByExampleTest.testJunctionNotExpressionQBE-Test schlägt in Sybase fehl, weil ansinull standardmäßig deaktiviert ist. Dieser Test erstellt ein ODER-Verknüpfungsprädikat wie ( OR^ (ex) (NOT ex) ). Dies sollte mit allem in der Datenbank übereinstimmen, da aber ANSI SQL alle NULL-Werte involvierenden Vergleiche als UNKNOWN evaluiert, wurden nicht alle Übereinstimmungen wiedergegeben. Um dieses Problem zu umgehen, hängen Sie folgenden String an die JDBC-URL an:
?SQLINITSTRING=set ansinull on
?SQLINITSTRING=set ansinull on
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Ist dies nicht möglich, so besteht eine Alternative darin, den folgenden Java-Code (oder einen ähnlichen) nach Erhalt einer Hibernate Session s auszuführen:
Beim Ordnen von Batch-Insert-Anweisungen werden eingebettete Klassen nicht berücksichtigt. Es gibt zwei Möglichkeiten, wie dieses Problem umgangen werden kann. Setzen Sie für die erste Möglichkeit ORDER_INSERTS auf FALSE, wenn eingebettete Klassen verwendet werden. Die zweite Möglichkeit ist, explizit session.save() auf untergeordneten Objekten aufzurufen, um deren SQL Insertion Orders zu erzwingen.
Auf Sybase wird der current_timestamp-Text vom Übersetzer nicht als ein Methodenmodus erkannt. Es gibt derzeit keine andere Möglichkeit, dieses Problem zu umgehen, als zu vermeiden, auf die Funktionsersetzung für current_timestamp angewiesen zu sein.
Auf Sybase kann SchemaExport nicht dazu verwendet werden, im verketteten Transaktionsmodus gespeicherte Prozeduren zu erzeugen. Fügen Sie zur Umgehung dieses Problems den folgenden Code unmittelbar nach der Definition der neuen gespeicherten Prozedur ein:
Die evict(Object)-Methode in EntityRegionAccessStrategy und CollectionRegionAccessStrategy versucht, Objekte aus dem Cache ohne Rücksicht auf die Transaktionsisolation zu entfernen. Dies wird derzeit nicht unterstützt, da die removeNode-Methode von JBoss Cache nicht mit Transaktionen arbeitet.
Das Einstellen einer Anfragezeitüberschreitung für ein PreparedStatement wird von PostgreSQL 8.3.7 nicht unterstützt. Diese Einschränkung bedeutet, dass Anfragen scheitern werden, wenn sie eine Annotation wie die folgende verwenden:
@QueryHint(name = "org.hibernate.timeout", value = "100")
@QueryHint(name = "org.hibernate.timeout", value = "100")
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Die Implementierung von Applikationen, die auf Hibernate zur Verwendung von cglib als Byte-Provider verweisen, schlägt aufgrund einer java.lang.SecurityException fehl. Eine Fehlermeldung ähnlich der folgenden wird ausgegeben:
Deployment "persistence.unit:unitName=lobtest.ear/
lobtest-ejb-1.0-SNAPSHOT.jar#lobtest-jpa-jndi" is in error due to the following reason(s):
java.lang.SecurityException: class
"com.redhat.gss.lobtest.jpa.Item$$EnhancerByCGLIB$$defd1a7f"'s signer information does not
match signer information of other classes in the same package
Deployment "persistence.unit:unitName=lobtest.ear/
lobtest-ejb-1.0-SNAPSHOT.jar#lobtest-jpa-jndi" is in error due to the following reason(s):
java.lang.SecurityException: class
"com.redhat.gss.lobtest.jpa.Item$$EnhancerByCGLIB$$defd1a7f"'s signer information does not
match signer information of other classes in the same package
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Der Grund hierfür liegt darin, dass cglib.jar in JBoss Enterprise Application Platform 5.0 signiert ist, und der mit cglib instrumentierte Proxy die cglib.jar-Signaturinformationen nutzt anstelle der Signaturinformationen der Zielklasse der Applikation.
cglib ist in der 5.1 Release der JBoss Enterprise Application Platform veraltet.
Sybase unterstützt derzeit keine Hibernate Blobs oder Clobs und Hibernate unterstützt keine Sybase text oder image Datentypen. Um dieses Problem zu umgehen, erzeugen Sie benutzerdefinierte Typen, die auf die Sybase text und image Typen verweisen.
Sybase fügt keine neue Entity ein, wenn sie ihre Spalte überfüllt. Allerdings meldet es keine Ausnahme, so dass Hibernate nicht bemerkt, dass das Einfügen fehlschlug. Um dieses Problem zu umgehen, verwenden Sie das jconn3.jar mit DYNAMIC_PREPARE=true in der Hibernate Konfigurationsdatei.
ShemaExport schlägt auf Oracle und Sybase fehl, wenn eine redundante @Column(unique=true) oder UniqueContraint(columnnames={...}) Annotation in einer Spalte verwendet wird, die vom deklarierten Modell implizit als eindeutig definiert ist. Um dieses Problem zu umgehen, entfernen Sie die redundante @Column(unique=true) oder UniqueContraint(columnnames={...}) Annotation.
Wenn der DB2 v9.7 Treiber mit progressivem Streaming verwendet wird (dies ist der Standard), schlagen Operationen auf Blob und Clob-Locators fehl. Um dieses Problem zu umgehen, gibt es zwei Möglichkeiten:
Erstellen Sie eine Property-Datei namens DB2JccConfiguration.properties entweder in Ihrem Klassenpfad oder in einem JAR in Ihrem Klassenpfad. Fügen Sie dieser Datei folgende Zeile hinzu, um progressives Streaming in DB2 zu deaktivieren:
db2.jcc.override.progressiveStreaming=2
db2.jcc.override.progressiveStreaming=2
Copy to ClipboardCopied!Toggle word wrapToggle overflow
Verwenden Sie den DB2 Version 9.1 Treiber statt DB2 Version 9.7.
Es besteht ein Problem mit dem DB2 v9.7 Treiber, wenn eine Identität oder ein nativer ID-Generator mit Hibernate verwendet wird. Die Statement.getGeneratedKeys()-Treibermethode in DB2 gibt eine leere Ergebnistabelle wieder anstelle der generierten Schlüssel. Infolgedessen meldet Hibernate eine Ausnahme, die besagt, dass die Datenbank keinen nativ generierten Identitätswert wiedergab. Dieses Problem wurde in der Version des DB2 9.7 JDBC Treibers behoben, der mit Data Studio 2.2 bereitgestellt wird, und steht auf der DB2-Website zum Download zur Verfügung. Diese Version wird zum Einsatz mit Hibernate empfohlen.
Die Save (speichern) Operation kann fehlschlagen, wenn eine flüchtige Entity über mehrere Pfade erreicht werden kann und mindestens einer dieser Pfade nicht für die Save-Operation kaskadiert. Um dieses Problem zu umgehen, sollten Sie die flüchtige Entity zunächst speichern, bevor Sie die zuvor fehlgeschlagene save-Operation ausführen. Ist dies nicht möglich, können Sie alternativ entweder einen oder beide Cascade- und Entity-Mappings ändern, um die Reihenfolge der Cascade-Pfade derart zu ändern, dass die flüchtige Entity gespeichert wird, bevor zu der Entity kaskadiert wird, die eine nicht-flüchtige Entity erfordert.
Die Hibernate Tests JoinTest.java und QueryAndSQLTest.java schlagen fehl, wenn Anfragen mit typenlosen Parametern für DB2 getestet werden, welches typenlose Parameter nicht unterstützt. Sie können dieses Problem umgehen, indem Sie die Anfragen so bearbeiten, dass die Parameter an die passenden Datentypen verteilt werden wie im JIRA beschrieben.
Nullwerte für Spalten markiert als Boolean in Sybase werden als 0 anstelle von null persistiert. Weisen Sie type="org.hibernate.test.where.NumericTrueFalseType" anstelle von type="boolean" zu, um dieses Problem zu umgehen.
Sybase erlaubt nur einen Eintrag (z.B. Spaltenname oder '*') in einer Unteranfrage-Select-Liste. Die HQL-Funktion, elements(), schlägt fehl, wenn das Collection-Element eine zusammengesetzte ID besitzt, da das generierte SQL eine Unteranfrage-Select-Liste mit mehreren Einträgen enthält. Um das Problem zu umgehen, vermeiden Sie die Verwendung von HQL elements(), wenn die Elemente einen zusammengesetzten Schlüssel enthalten. Wandeln Sie stattdessen die HQL so um, dass keine Unterabfrage mehrere Einträge in ihrer Auswahlliste hat.
In Sybase, wenn eine Abfrage ein ANSI-Join besitzt mit drei oder mehr Joins und einer dieser Joins eine Union-Unterklasse umfasst, kann die Abfrage mit einer SybSQLException fehlschlagen, da eine Spalte nicht innerhalb des Geltungsbereichs des Joined-Table-Ausdrucks liegt. Derzeit wird empfohlen, die Verwendung von Join-Fetches im Zusammenhang mit Union-Unterklassen zu vermeiden.
Wenn eine DetachedCriteria als Unterabfrage verwendet wird, enthält die generierte SQL einen Spaltenalias in der Unterabfrage. Auf Sybase wird dadurch eine SybSQLException gemeldet, da Sybase keine Spaltenaliasse in Unterabfragen zulässt. Um dieses Problem zu umgehen, verwenden Sie in einer Unterabfrageeine eine HQL-Abfrage anstelle einer DetachedCriteria.
Wenn @OrderBy auf Joined-Klassen verwendet wird (mittels einer Join-Tabelle), ist das generierte SQL auf MySQL, PostgreSQL, Oracle und MSSQL ungültig, da die "order by"-Klausel die Spalten unter Verwendung des tatsächlichen Tabellennamens qualifiziert. Die "order by"-Klausel sollte stattdessen den Tabellenalias verwenden.
Wenn eine char-Eigenschaft verwendet wird und diese nicht initialisiert wird, so initialisiert Hibernate sie zu 0 und persistiert einen String, der das Zeichen \u0000 enthält. PostgreSQL meldet eine Ausnahme, da es das Zeichen \u0000 nicht in einem String eingebettet zulässt. Das Problem der Persistierung von \u0000 in einer char-Spalte mittels PostgreSQL lässt sich derzeit nicht beheben.
Falls der Benutzer beabsichtigt, eine NULL als eine nicht initialisierte char-Property anstelle von \u0000 zu persistieren, dann sollte java.lang.Character verwendet werden anstelle des primitiven char-Typs. Dies verhindert die Ausnahme beim Initialisieren der Property. Der Versuch, eine java.lang.Character-Property zu persistieren, die auf \u0000 gesetzt ist, verursacht nach wie vor eine Ausnahme.
In manchen Fällen, wenn Fremdschlüsseleinschränkungen auf Spalten in einem Primärschlüssel definiert sind, deklariert SchemaExport diese fälschlicherweise als nullbar, wenn es CREATE TABLE-Anweisungen generiert. Dies schlägt auf MSSQL, DB2 und Sybase fehl, da diese Datenbanken erfordern, dass Primärschlüsselspalten nicht nullbar sind.
Um dieses Problem zu umgehen, legen Sie eindeutig fest, welche Spalten nicht nullbar sein sollen, z.B:
Fügen Sie nullable=false zu @JoinColumn hinzu
Fügen Sie optional=false zu @ManyToOne hinzu
Fügen Sie @AttributeOverride mit @Column(name="mapkey", nullable=false) hinzu, falls eine @CollectionOfElements eine Map verwendet
Fügen Sie nullable=false in @Column hinzu, wenn innerhalb einer @CollectionId oder innerhalb einer @MapKey
Wir helfen Red Hat Benutzern, mit unseren Produkten und Diensten innovativ zu sein und ihre Ziele zu erreichen – mit Inhalten, denen sie vertrauen können. Entdecken Sie unsere neuesten Updates.
Mehr Inklusion in Open Source
Red Hat hat sich verpflichtet, problematische Sprache in unserem Code, unserer Dokumentation und unseren Web-Eigenschaften zu ersetzen. Weitere Einzelheiten finden Sie in Red Hat Blog.
Über Red Hat
Wir liefern gehärtete Lösungen, die es Unternehmen leichter machen, plattform- und umgebungsübergreifend zu arbeiten, vom zentralen Rechenzentrum bis zum Netzwerkrand.