Hi
I am trying to persist geometry objects as Oracle SDO_GEOMETRY data.
In my test case, I am able to persist an Oracle JGeometry object using oracle.sql.STRUCT in the table column via JDBC.
Code:
int elementInfo[] = {1, 2, 1};
double ordinates[] =
{719662.21, 6182614.33, 719673.88, 6182600.43};
JGeometry lineString =
new JGeometry(2002, 1234, elementInfo, ordinates);
STRUCT geoObj = JGeometry.store(lineString, connection);
PreparedStatement prepStatement =
connection.prepareStatement
("insert into MisoGeometry (id, geometry)
values (MisoGeometry_id_seq.nextval, ?)");
prepStatement.setObject(1, geoObj, Types.STRUCT);
I now want Hibernate to do the save.
What I have tried is to implement a UserType (STRUCTUserType, see below) containing a STRUCT object, and then map it to the table (user type, mapping and table below).
However, now I cannot instantiate my test case. HbmBinder is able to resolve properties of class MisoGeometry and table MISOGEOMETRY, but startup fails at reference resolving with
Code:
java.lang.reflect.InvocationTargetException
(see below).
Has anyone succeeded saving geometry using Hibernate 3.0?
Thanks
Hibernate version: 3.0.5 Mapping documents:Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class
name="dk.xxx.myproject.matrikulaerbasis.model.MisoGeometry"
table="MisoGeometry"
>
<id
name="id"
column="id"
type="long"
>
<generator class="native">
<param name="sequence">misogeometry_id_seq</param>
</generator>
</id>
<property
name="geometry"
type="STRUCTUserType"
update="true"
insert="true"
>
<column
name="geometry"
sql-type="sdo_geometry"
/>
</property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
public class STRUCTUserType implements UserType {
private STRUCT oracleSqlStructUserType;
public STRUCT getOracleSqlStructUserType() {
return oracleSqlStructUserType;
}
public void setOracleSqlStructUserType(STRUCT oracleSqlStructUserType) {
this.oracleSqlStructUserType = oracleSqlStructUserType;
}
public int[] sqlTypes() {
return new int[Types.STRUCT];
}
public Class returnedClass() {
return STRUCT.class;
}
public boolean equals(Object obj1, Object obj2) throws HibernateException {
return ((STRUCT)obj1).equals((STRUCT)obj2);
}
public int hashCode(Object o) throws HibernateException {
return ((STRUCT)o).hashCode();
}
public Object nullSafeGet(ResultSet resultSet, String[] strings, Object o) throws HibernateException, SQLException {
STRUCT geometry = (STRUCT) resultSet.getObject(strings[0]);
return resultSet.wasNull() ? null : geometry;
}
public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i) throws HibernateException, SQLException {
if (o == null) {
preparedStatement.setNull(i, Types.STRUCT);
} else {
preparedStatement.setObject(i, (STRUCT) o);
}
}
public Object deepCopy(Object o) throws HibernateException {
if(o==null) {
return null;
} else {
STRUCT geo = (STRUCT) o;
STRUCT newGeo;
try {
newGeo = new STRUCT(geo.getDescriptor(),geo.getConnection(),geo.getAttributes());
} catch (SQLException e) {
e.printStackTrace();
throw new HibernateException("deepCopy SQLException", e);
}
return newGeo;
}
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object o) throws HibernateException {
return (Serializable) deepCopy(o);
}
public Object assemble(Serializable serializable, Object o) throws HibernateException {
return deepCopy(serializable);
}
public Object replace(Object o, Object o1, Object o2) throws HibernateException {
return (STRUCT) o;
}
Full stack trace of any exception that occurs:As you can see, HbmBinder is able to resolve properties of class MisoGeometry and table, but fails at reference resolving with java.lang.reflect.InvocationTargetException.
Code:
...
17:29:26,644 DEBUG [org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1262)] myproject/hibernate/SessionFactory<-org.dom4j.tree.DefaultAttribute@977dd28 [Attribute: name resource value "dk/xxx/myproject/matrikulaerbasis/model/misogeometry.hbm.xml"]
17:29:26,644 INFO [org.hibernate.cfg.Configuration.addResource(Configuration.java:444)] Mapping resource: dk/xxx/myproject/matrikulaerbasis/model/misogeometry.hbm.xml
17:29:26,654 DEBUG [org.hibernate.util.DTDEntityResolver.resolveEntity(DTDEntityResolver.java:42)] trying to locate http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd in classpath under org/hibernate/
17:29:26,654 DEBUG [org.hibernate.util.DTDEntityResolver.resolveEntity(DTDEntityResolver.java:53)] found http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd in classpath
17:29:26,684 INFO [org.hibernate.cfg.HbmBinder.bindRootPersistentClassCommonValues(HbmBinder.java:260)] Mapping class: dk.xxx.myproject.matrikulaerbasis.model.MisoGeometry -> MisoGeometry
17:29:26,684 DEBUG [org.hibernate.cfg.HbmBinder.bindProperty(HbmBinder.java:1099)] Mapped property: id -> id
17:29:26,684 DEBUG [org.hibernate.cfg.HbmBinder.bindProperty(HbmBinder.java:1099)] Mapped property: geometry -> geometry
...
17:29:26,814 DEBUG [org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:964)] resolving reference to class: dk.xxx.myproject.sag.model.Sag
17:29:26,814 DEBUG [org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:964)] resolving reference to class: dk.xxx.myproject.sag.model.Sagshaendelse
17:29:26,814 DEBUG [org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:964)] resolving reference to class: dk.xxx.myproject.sagspakke.model.Sagspakke
Cannot instantiate test(s): java.lang.reflect.InvocationTargetException
Process finished with exit code 1
Name and version of the database you are using:Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Production
With the Partitioning, OLAP and Data Mining options
The generated SQL (show_sql=true):No SQL to access table MISOGEOMETRY is created due to the reflection error. The table definition is:
Code:
create table myproject.MisoGeometry (
id number(19,0) not null,
geometry sdo_geometry,
primary key (id)
);
create sequence myproject.misogeometry_id_seq;
Debug level Hibernate log excerpt: