Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Problem persisting TimestampTZ with JPA
Problem persisting TimestampTZ with JPA [message #737095] Fri, 14 October 2011 16:52 Go to next message
Jeremy Purdy is currently offline Jeremy PurdyFriend
Messages: 7
Registered: October 2011
Junior Member
Versions
Eclipselink 2.1
Oracle 10.2.0.4
Tomcat 5.5.26

Using JPA, I am attempting to persist a java.util.Calendar object to an Oracle Timestamp With Time Zone column. From what I have read, Eclipselink is supposed to just handle this for Oracle DB.

However, an attempt at a direct mapping:

@Entity
@Table(name="TIMESTAMP_TZ_TEST")
public class TimestampTzTest {
	@Id
	private Long id;
	@Column(name="TIME")
	private Calendar time;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public Calendar getTime() {
		return time;
	}
	
	public void setTime(Calendar time) {
		this.time = time;
	}
}


fails during startup because
The attribute [time] from the entity class [class eg.model.TimestampTzTest] does not specify a temporal type.


Next, I try using a TypeConverter

	@Column(name="TIME")
	@Convert("timestamptz")
	@TypeConverter(name="timestamptz", dataType=TIMESTAMPTZ.class)
	private Calendar time;


This results in an error during execution:
Caused by: java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingCallableStatement cannot be cast to oracle.jdbc.OracleCallableStatement
	at oracle.sql.TRANSDUMP.getTransitions(TRANSDUMP.java:42)
	at oracle.sql.TIMEZONETAB.updateTable(TIMEZONETAB.java:456)
	at oracle.sql.TIMESTAMPTZ.toTimestamp(TIMESTAMPTZ.java:571)
	at oracle.sql.TIMESTAMPTZ.timestampValue(TIMESTAMPTZ.java:731)
	at org.eclipse.persistence.platform.database.oracle.Oracle9Platform.getTIMESTAMPTZFromResultSet(Oracle9Platform.java:192)


From what I have found during search, this appears to be caused by the Tomcat connection pool not returning the underlying OracleCallableStatement.

I have not been able to find a solution to this problem. Can someone please guide me?
Re: Problem persisting TimestampTZ with JPA [message #739728 is a reply to message #737095] Mon, 17 October 2011 19:49 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

To support TIMESTAMPTZ EclipseLink needs access to the real JDBC connection.

If you are using a DataSource you need to set a ServerPlatform in EclipseLink that can unwrap the connection.
Log an enhancement request to have a platform added for Tomcat, it should be pretty simple to implement, so consider contributing it if you do.


James : Wiki : Book : Blog : Twitter
Re: Problem persisting TimestampTZ with JPA [message #739865 is a reply to message #739728] Mon, 17 October 2011 23:43 Go to previous messageGo to next message
Jeremy Purdy is currently offline Jeremy PurdyFriend
Messages: 7
Registered: October 2011
Junior Member
Thanks for the idea, I will give that a try and report the results.
Re: Problem persisting TimestampTZ with JPA [message #741541 is a reply to message #739865] Wed, 19 October 2011 16:20 Go to previous messageGo to next message
Jeremy Purdy is currently offline Jeremy PurdyFriend
Messages: 7
Registered: October 2011
Junior Member
It took a while to figure out how to unwrap the Tomcat DBCP Connection, until I found out that Spring has a helper method to do it. Here is my implemented TomcatServerPlatform, which has not been fully tested but works for this current scenario:

import java.sql.Connection;
import java.sql.SQLException;

import org.eclipse.persistence.platform.server.ServerPlatformBase;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor;

public class TomcatServerPlatform extends ServerPlatformBase {

	public TomcatServerPlatform(DatabaseSession newDatabaseSession) {
		super(newDatabaseSession);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Class getExternalTransactionControllerClass() {
		return null;
	}

	@Override
	public Connection unwrapConnection(Connection connection) {
		CommonsDbcpNativeJdbcExtractor nje = new CommonsDbcpNativeJdbcExtractor();
		
		try {
			connection = nje.getNativeConnection(connection);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return connection;
	}
}


Configuring JPA to utilize this class requires the following properties within the persistence.xml:

<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.oracle.Oracle10Platform"/>
<property name="eclipselink.target-server" value="data.jpa.eclipselink.support.TomcatServerPlatform"/>


Using the TypeConverter annotation listed previously this works properly and I am able to persist the Calendar object to a TIMESTAMP WITH TIME ZONE column.

Note that this implementation requires that you are using Spring. Because of this, this solution would not be a valid consideration to be included in Eclipselink for general use. I have been largely unsuccessful in unwrapping the DBCP connection without this Spring helper. If someone wants to try to figure that out, feel free.
Re: Problem persisting TimestampTZ with JPA [message #741542 is a reply to message #739865] Wed, 19 October 2011 16:21 Go to previous message
Jeremy Purdy is currently offline Jeremy PurdyFriend
Messages: 7
Registered: October 2011
Junior Member
It took a while to figure out how to unwrap the Tomcat DBCP Connection, until I found out that Spring has a helper method to do it. Here is my implemented TomcatServerPlatform, which has not been fully tested but works for this current scenario:

import java.sql.Connection;
import java.sql.SQLException;

import org.eclipse.persistence.platform.server.ServerPlatformBase;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor;

public class TomcatServerPlatform extends ServerPlatformBase {

public TomcatServerPlatform(DatabaseSession newDatabaseSession) {
super(newDatabaseSession);
}

@SuppressWarnings("unchecked")
@Override
public Class getExternalTransactionControllerClass() {
return null;
}

@Override
public Connection unwrapConnection(Connection connection) {
CommonsDbcpNativeJdbcExtractor nje = new CommonsDbcpNativeJdbcExtractor();

try {
connection = nje.getNativeConnection(connection);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return connection;
}
}


Configuring JPA to utilize this class requires the following properties within the persistence.xml:

<property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.oracle.Oracle10Platform"/>
<property name="eclipselink.target-server" value="data.jpa.eclipselink.support.TomcatServerPlatform"/>


Using the TypeConverter annotation listed previously this works properly and I am able to persist the Calendar object to a TIMESTAMP WITH TIME ZONE column.

Note that this implementation requires that you are using Spring. Because of this, this solution would not be a valid consideration to be included in Eclipselink for general use. I have been largely unsuccessful in unwrapping the DBCP connection without this Spring helper. If someone wants to try to figure that out, feel free.
Previous Topic:what maven artefact for (DynamicJaxbContext with xsd) ...jaxb.dynamic.metadata.SchemaMetadata
Next Topic:Controlling column order when creating tables with ddl-generation
Goto Forum:
  


Current Time: Thu Nov 27 05:48:41 GMT 2014

Powered by FUDForum. Page generated in 0.06194 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software