Bonjour,
Je souhaiterais utiliser les fichiers de mappings (persistence.xml) pour mapper un modèle de données java vers une base SQL.
Le modèle java est dans une librairie (un jar) et je n'ai pas la possibilité de le modifier (donc pas d'annotation ...)
Tout se passait assez bien jusqu'à ce que je rencontre le problème suivant.
Je souhaite faire persister la classe Pixels. Elle contient des attributs de type PositiveInteger, type qui étent NonNegativeInteger lui même étendant la classe générique PrimitiveType.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 public class Pixels extends AbstractOMEModelObject { // Property private String id; // Property private PositiveInteger sizeT; .... }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 public class PositiveInteger extends NonNegativeInteger { public PositiveInteger(Integer value) { super(value); if (value == null || value.intValue() < 1) { throw new IllegalArgumentException( value + " must not be null and positive."); } } public static PositiveInteger valueOf(String s) { return new PositiveInteger(Integer.valueOf(s)); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 public class NonNegativeInteger extends PrimitiveType<Integer> { public NonNegativeInteger(Integer value) { super(value); if (value == null || value.intValue() < 0) { throw new IllegalArgumentException( value + " must not be null or non-negative."); } } public static NonNegativeInteger valueOf(String s) { return new NonNegativeInteger(Integer.valueOf(s)); } }Pour mapper tout ça j'ai écrit le fichier orm.xml suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public abstract class PrimitiveType<T> { /** The delegate value. */ T value; /** * Default constructor. * @param value The delegate value to use. */ PrimitiveType(T value) { this.value = value; } /** * Default constructor. * @param value The delegate value to use. */ PrimitiveType() { } /** * Retrieves the concrete delegate value. * @return See above. */ public T getValue() { return value; } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return value.toString(); } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj instanceof PrimitiveType<?>) { return value.equals(((PrimitiveType<?>) obj).getValue()); } return value.equals(obj); }
J'utilise eclipselink comme implementation.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 <?xml version="1.0" encoding="UTF-8"?> <entity-mappings version="2.0" xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"> <persistence-unit-metadata> <persistence-unit-defaults> <access>FIELD</access> </persistence-unit-defaults> </persistence-unit-metadata> <mapped-superclass class="ome.xml.model.primitives.NonNegativeInteger"></mapped-superclass> <mapped-superclass class="ome.xml.model.primitives.PrimitiveType"> <attributes> <basic name="value"></basic> </attributes> </mapped-superclass> <entity class="ome.xml.model.Pixels"> <attributes> <id name="id"></id> <basic name="sizeT"><column name="sizeT"/> </basic> <transient name="channels"/> <transient name="binDataBlocks"/> <transient name="tiffDataBlocks"/> <transient name="metadataOnly"/> <transient name="planes"/> <transient name="annotationLinks"/> ... </attributes> </entity> </entity-mappings>
Le test suivant fonctionne
mais évidemment dans la BD, il met un BLOB au lieu d'un entier...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 @Test public void extractMetadata() { Pixels pixels = new Pixels(); pixels.setId("toto"); pixels.setPositiveIntger (new PositiveInteger(10)); em.persist(pixels) }
si je force la définition de la colonne avec un <basic name="sizeT"><column name="sizeT" column-definition="integer"/>
j'obtient l'exception:
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Incorrect integer value: '\xAC\xED\x00\x05sr\x00(ome.xml.model.primitives.PositiveInteger\xC3\xAD\x83\xD2\xC9\xD2\xDD\x8C\x02\x00\x00xr\x00+ome.xml.model.' for column 'sizeT' at row 1
Error Code: 1366
Call: INSERT INTO PIXELS (ID, DIMENSIONORDER, PHYSICALSIZEX, PHYSICALSIZEY, PHYSICALSIZEZ, SIZEC, sizeT, sizeX, SIZEY, SIZEZ, TIMEINCREMENT, TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
bind => [12 parameters bound]
Query: InsertObjectQuery(ome.xml.model.Pixels@320b34b1)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
...
quelqu'un connait-il un moyen de faire persister cette colonne avec un type entier, sans toucher au code java bien sûr ?
Partager