How can I customize the CMP Field mapping in EAP6
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 6.x
Issue
- How can I customize JDBC statements for EJB (CMP) Entity fields
- There is a class not found Exception if I migrate the CMP mapper from EAP5 to EAP6
Resolution
To customize the mapping you need to implement the interfaces JDBCParameterSetter
JDBCResultSetReader
and adjust the application configuration.
create a mapping for the jbosscmp-jdbc.xml in your application
<jbosscmp-jdbc>
<defaults>
<datasource>java:jboss/datasources/yourDSname</datasource>
<!-- with EAP6 you need to set the mapping inside the application defaults -->
<datasource-mapping>Oracle9i_withTimestampMapping</datasource-mapping>
</defaults>
...
<type-mappings>
<name>Oracle9i_withTimestampMapping</name>
...
<mapping>
<java-type>java.sql.Timestamp</java-type>
<jdbc-type>TIMESTAMP</jdbc-type>
<sql-type>TIMESTAMP(3) WITH TIME ZONE</sql-type>
<param-setter>org.jboss.cmp.OracleTimestampMapper</param-setter>
<result-reader>org.jboss.cmp.OracleTimestampMapper</result-reader>
</mapping>
</type-mappings>
A template for the mapping can be taken from the standardjbosscmp-jdbc.xml which is in the configuration folder of EAP4/EAP5 or within the org/jboss/as/cmp module archive.
Create the mapper class
This example store the date in an Oracle column with the current Timezone
public final class OracleTimestampMapper implements JDBCParameterSetter, JDBCResultSetReader {
public void set(PreparedStatement ps, int index, int jdbcType, Object value, Logger log) throws SQLException {
// get the underlying Oracle Statement
WrappedPreparedStatement wps = (WrappedPreparedStatement) ps;
OraclePreparedStatement ops = (OraclePreparedStatement) wps.getUnderlyingStatement();
if (value == null) {
ops.setNull(index, jdbcType);
} else {
// store Oracle specific Timestamp into the TIMESTAMP WITH TIMEZONE column
TIMESTAMPTZ ts;
java.sql.Timestamp dt = (java.sql.Timestamp) value;
ts = new TIMESTAMPTZ(ops.getConnection(), dt, Calendar.getInstance());
ops.setTIMESTAMPTZ(index, ts);
}
}
public Object get(ResultSet rs, int index, Class destination, Logger log) throws SQLException {
return rs.getTimestamp(index);
}
Root Cause
The Mapper interface is moved to a different package. From org.jboss.ejb.plugins.cmp.jdbc
to org.jboss.as.cmp.jdbc
.
There is an issue with classloading and it is necessary to add the custom module to the cmp subsystem as dependency. BZ924548
From 6.3.2 on this is not longer necessary as the class will be loaded from the applications classloader.
Related articles
Field mapping for custom classes in EAP6
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments