2017-01-11 5 views
2

私は 輸入java.util.UUIDとしてJPAのためのAttributeConverterが定義されているドメインJaybird(CHAR(16)文字セットオクテット)

CREATE DOMAIN OCTET16 AS CHAR(16) CHARACTER SET OCTETS; 

によって定義されたUUID IDフィールドに問題があります。それは

私は問題を仮定しないバイナリ表現が、36文字のテキスト形式を変換しようとして

@Id 
@Convert(converter = UUIDAttributeConverter.class) 
private UUID id; 

が、JPA(EclipseLinkは+ Eclipseのジェミニ)として

import javax.persistence.AttributeConverter; 
import javax.persistence.Converter; 

import com.ekser.nakkash.icdv.tools.UUIDTools; 

@Converter 
public class UUIDAttributeConverter implements AttributeConverter<UUID, byte[]> { 
    @Override 
    public byte[] convertToDatabaseColumn(UUID arg0) { 
     return UUIDTools.asBytes((UUID) arg0); 
    } 
    @Override 
    public UUID convertToEntityAttribute(byte[] arg0) { 
     return UUIDTools.asUUID((byte[])arg0); 
    } 
} 

と定義されたJPAのフィールドは、エラーになりますjaybirdがCHAR(16)としてフィールドの型を与えていることです(ResultSetMetaDataでチェックしました)。 octetsAsBytesがあり、jbdcのURLと同じように使用しています。

jdbc:firebirdsql:localhost:D:/aktarma-12-13/VERI.FDB?octetsAsBytes=true 

結果はありません。

私のセットアップは、だから私はBINARY問題が消えますようにResultSetMetaDataは私のフィールドの型を与えるときだと思う

Java 1.8 
Efxclipse 2.4.0 RCP 
Firebird 2.5.6 
Jaybird 2.2.12 JDK_1.8 
HikariCP 2.4.1 
EclipseLink 2.6.4 
Eclipse Gemini 1.2.0.M1 

かなり複雑です。しかしどうですか?助言がありますか。

idsをchar(32)またはchar(36)として保持したくないだけです。

編集:Jaybird 3.beta-2に切り替えた後、 一つは第三のラインinvalid stream header: F1505533明らかに見ることができます。これは部分的にASCIIデコードされたid(char(16)文字集合オクテット)です。この値を生のバイトとして受け入れ、JPAにUUIDAttributeConverterクラスを渡す方法を教えてください。

Exception in thread "JavaFX Application Thread" javax.persistence.PersistenceException: Exception [EclipseLink-66] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: Could not deserialize object from byte array. 
Internal Exception: java.lang.RuntimeException: java.io.StreamCorruptedException: invalid stream header: F1505533 
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[id-->YAZDIRMA_TURLERI.ID] 
Descriptor: RelationalDescriptor(com.ekser.nakkash.icdv.pojo.YazdirmaTuru --> [DatabaseTable(YAZDIRMA_TURLERI)]) 
    at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:484) 
    at com.ekser.nakkash.icdv.gui.MainPartIcdv.lambda$1(MainPartIcdv.java:180) 
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) 
    at javafx.event.Event.fireEvent(Event.java:198) 
    at javafx.scene.Node.fireEvent(Node.java:8413) 
    at javafx.scene.control.Button.fire(Button.java:185) 
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182) 
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96) 
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) 
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) 
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) 
    at javafx.event.Event.fireEvent(Event.java:198) 
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757) 
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) 
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) 
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416) 
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415) 
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555) 
    at com.sun.glass.ui.View.notifyMouse(View.java:937) 
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: Exception [EclipseLink-66] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: Could not deserialize object from byte array. 
Internal Exception: java.lang.RuntimeException: java.io.StreamCorruptedException: invalid stream header: F1505533 
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[id-->YAZDIRMA_TURLERI.ID] 
Descriptor: RelationalDescriptor(com.ekser.nakkash.icdv.pojo.YazdirmaTuru --> [DatabaseTable(YAZDIRMA_TURLERI)]) 
    at org.eclipse.persistence.exceptions.DescriptorException.notDeserializable(DescriptorException.java:1232) 
    at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertDataValueToObjectValue(SerializedObjectConverter.java:144) 
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getObjectValue(AbstractDirectMapping.java:616) 
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1220) 
    at org.eclipse.persistence.mappings.DatabaseMapping.readFromRowIntoObject(DatabaseMapping.java:1539) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoObject(ObjectBuilder.java:462) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:1005) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneNormally(ObjectBuilder.java:899) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:852) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:735) 
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:689) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:805) 
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:962) 
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:573) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1175) 
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:904) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1134) 
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:460) 
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1222) 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839) 
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804) 
    at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258) 
    at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:473) 
    ... 56 more 
Caused by: java.lang.RuntimeException: java.io.StreamCorruptedException: invalid stream header: F1505533 
    at org.eclipse.persistence.sessions.serializers.JavaSerializer.deserialize(JavaSerializer.java:57) 
    at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertDataValueToObjectValue(SerializedObjectConverter.java:142) 
    ... 79 more 
Caused by: java.io.StreamCorruptedException: invalid stream header: F1505533 
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source) 
    at java.io.ObjectInputStream.<init>(Unknown Source) 
    at org.eclipse.persistence.internal.helper.CustomObjectInputStream.<init>(CustomObjectInputStream.java:37) 
    at org.eclipse.persistence.sessions.serializers.JavaSerializer.deserialize(JavaSerializer.java:53) 
    ... 80 more 
+0

書き込み時にドライバがバイト[]を処理できるかどうかは、読み込み時のみ問題ですか?その場合は、ドライバから返された文字列をコンバーターで処理してください。 – Chris

+1

[Jaybird 3-beta-2](https://github.com/FirebirdSQL/jaybird/releases/tag/v3.0.0-beta-2)で試してみてください。 'char(16)character set octets '型は' binary'型として常に、[JDBC(VAR)BINARYとして扱われる文字セットOCTETS](https://www.firebirdsql.org/file/documentation/drivers_documentation/java/3.0.0-beta-2/release_notesを参照してください。 html#character-set-octets-as-jdbc-varbinary)を使用します。残念ながら、Jaybird 2.2の 'octetsAsBytes'は一貫して適用されません(' ResultSetMetaData'の場合には適用されますが、例えば 'getObject'が結果セットで使用されていると動作しません)。 –

+0

ご参考まで:ご質問に実際のエラーを含めると便利です。 –

答えて

1

私はこれをテストするためのEclipseLink 2.6.4を使用して簡単なプロジェクトを行っている、とJaybird 2.2.12(octetsAsBytes=trueを設定することが必須である)とJaybird 3.0.0-β-2との両方が、それは動作します:

また、上の

コード:https://gist.github.com/mrotteveel/273aa9e836880211820f54ff21164ec1

藤堂エンティティ:

package com.example.eclipselink.entity; 

import com.example.eclipselink.converter.UUIDAttributeConverter; 

import javax.persistence.Convert; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import java.util.UUID; 

@Entity 
public class Todo { 

    @Id 
    @Convert(converter = UUIDAttributeConverter.class) 
    private UUID id; 

    public UUID getId() { 
     return id; 
    } 

    public void setId(UUID id) { 
     this.id = id; 
    } 
} 

UUIDAttributeConverter:

package com.example.eclipselink.converter; 

import javax.persistence.AttributeConverter; 
import javax.persistence.Converter; 
import java.nio.ByteBuffer; 
import java.util.UUID; 

@Converter 
public class UUIDAttributeConverter implements AttributeConverter<UUID, byte[]> { 

    @Override 
    public byte[] convertToDatabaseColumn(UUID uuid) { 
     if (uuid == null) return null; 
     byte[] buffer = new byte[16]; 
     ByteBuffer bb = ByteBuffer.wrap(buffer); 
     bb.putLong(uuid.getMostSignificantBits()); 
     bb.putLong(uuid.getLeastSignificantBits()); 
     return buffer; 
    } 

    @Override 
    public UUID convertToEntityAttribute(byte[] bytes) { 
     if (bytes == null) return null; 
     ByteBuffer bb = ByteBuffer.wrap(bytes); 
     long high = bb.getLong(); 
     long low = bb.getLong(); 
     return new UUID(high, low); 
    } 
} 

メイン:

package com.example.eclipselink; 

import com.example.eclipselink.entity.Todo; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 
import javax.persistence.Query; 
import java.util.List; 
import java.util.UUID; 

public class Main { 
    private static final String PERSISTENCE_UNIT_NAME = "todos"; 
    private static EntityManagerFactory factory; 

    public static void main(String[] args) { 
     factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
     EntityManager em = factory.createEntityManager(); 
     // read the existing entries and write to console 
     Query q = em.createQuery("select t from Todo t"); 
     List<Todo> todoList = q.getResultList(); 
     for (Todo todo : todoList) { 
      System.out.println(todo.getId()); 
     } 
     System.out.println("Size: " + todoList.size()); 

     // create new todo 
     em.getTransaction().begin(); 
     Todo todo = new Todo(); 
     todo.setId(UUID.randomUUID()); 
     em.persist(todo); 
     em.getTransaction().commit(); 

     em.close(); 
    } 
} 

永続コンテキスト:

<?xml version="1.0" encoding="UTF-8" ?> 
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
      version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> 
    <persistence-unit name="todos" transaction-type="RESOURCE_LOCAL"> 
     <class>com.example.eclipselink.entity.Todo</class> 
     <class>com.example.eclipselink.converter.UUIDAttributeConverter</class> 
     <properties> 
      <property name="javax.persistence.jdbc.driver" value="org.firebirdsql.jdbc.FBDriver" /> 
      <property name="javax.persistence.jdbc.url" 
         value="jdbc:firebirdsql://localhost/d:/data/db/fb3/eclipselink.fdb?charSet=UTF-8&amp;octetsAsBytes=true" /> 
      <property name="javax.persistence.jdbc.user" value="sysdba" /> 
      <property name="javax.persistence.jdbc.password" value="masterkey" /> 
     </properties> 

    </persistence-unit> 
</persistence> 

DDL:いくつかの実行後

CREATE TABLE TODO 
(
    ID char(16) CHARACTER SET OCTETS NOT NULL, 
    CONSTRAINT PK_TODO PRIMARY KEY (ID) 
); 

出力:

[EL Info]: 2017-01-13 15:59:14.733--ServerSession(1139700454)--EclipseLink, version: Eclipse Persistence Services - 2.6.4.v20160829-44060b6 
[EL Info]: connection: 2017-01-13 15:59:15.093--ServerSession(1139700454)--/file:/D:/Development/project/eclipselink/target/classes/_todos login successful 
4c062d69-849e-4946-8e25-edfc5d7441be 
dac10396-cfe2-4fb0-b048-65f954a82da5 
8dab770e-ebd2-4ebc-a29b-4b8aae0b449a 
9d376c67-fdc5-4e21-8013-f71cde5119aa 
Size: 4 
+0

あなたの質問に言及したようなドメインを使用して、私はそれを安全面でテストしました。 –

+0

マーク、あなたは私のヒーローです!あなたは私を二度目に救っています。私はこれを忘れないだろう。私のコードは大丈夫だった。私は@Converterアノテーションでuuidフィールドに注釈を付けることを忘れていました。私の他のAttibuteConvertersには(autoApply = true)があります。 .... –