Persistance d'un type générique
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:
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:
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:
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));
}
} |
Code:
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);
} |
Pour mapper tout ça j'ai écrit le fichier orm.xml suivant :
Code:
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> |
J'utilise eclipselink comme implementation.
Le test suivant fonctionne
Code:
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)
} |
mais évidemment dans la BD, il met un BLOB au lieu d'un entier...:calim2:
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)
...
:aie:
quelqu'un connait-il un moyen de faire persister cette colonne avec un type entier, sans toucher au code java bien sûr ?