Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » I need some help on adding StructConverters programatically.(StructConverters for user defined types in Oracle)
I need some help on adding StructConverters programatically. [message #889858] Wed, 20 June 2012 01:32 Go to next message
Sumitro Palit is currently offline Sumitro Palit
Messages: 2
Registered: June 2012
Junior Member
// -----------
// Preamble
//------------
In our system, we make heavy use of user defined types. Most tables have multiple fields that are user defined types , some of which could be repeated within a table.
eg. Table_1 might have columns of type FOO1, FOO2, FOO3 and another FOO3. Table_2 might have columns of type FOO1, FOO2 and FOO4.

Our goal is to use StructConverters to do the mapping and also keep the configuration of the mapping (annotations) least intrusive. Ideally I would do this programatically ( or through sessions.xml if that is easier but prefer using a pure JPA soulution).

We are using EclipseLink 2.3.2 in Eclipse Indigo + maven to run from command line.


//----------
// Question
//----------
I added my own SessionCustomizer and called addStructConverter() on the session (DataBasePlatform).

public class MySessionCustomizer extends SessionCustomizer {

public void customize(Session session) {
DatabasePlatform dp = (DatabasePlatform) session
.getDatasourcePlatform();
dp.addStructConverter(new Foo1Converter());
dp.addStructConverter(new Foo2Converter());
}
}

My understanding was that this approach would work if "public String getStructName()" and "public Class getJavaType()" are implemented on Foo1Converter & Foo2Converter - so no annotations would be necessary at the individual getter methods. However this approach is not working.

I am getting errors like:
Exception Description: The object [Foo1 [x=217.8., basis=std, description=null]], of class [class com.test.jpa.usertype.Foo1], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[foo1-->TABLE1.FOO1]] with descriptor [RelationalDescriptor(com.test.jpa.Table1 --> [DatabaseTable(TABLE1)])], could not be converted to [class [B].
at org.eclipse.persistence.exceptions.ConversionException.couldNotBeConverted(ConversionException.java:71)

The documentation for addStructConverter() says "Call this method within your EclipseLink session (server or database) prior to the session login ".
How do we achieve this programatically or do I need to use a sessions.xml configuration.

Does anyone have an example project (eclipse or maven) that uses multiple structconverters that way we are trying to use them.


//------------
// Note that we have used annotations to make the converters work but prefer to add these transparently via a session customizer class.
//------------
------------------------------------------------
So far, I have been able to make it work by using StructConverters/StructConverter/Convert annotations, ex:
// on any entity
@StructConverters(value = {
@StructConverter(name = "Foo1Converter", converter = "com.test.jpa.converters.Foo1Converter"),
@StructConverter(name = "Foo2Converter", converter = "com.test.jpa.converters.Foo2Converter") })


@Convert(value = "Foo1Converter")
@Column(name = "FOO1")
public Foo1 getFoo1() {
return this.foo1;
}
@Convert(value = "Foo2Converter")
@Column(name = "FOO2")
public Foo2 getFoo2() {
return this.foo2;
}

This works, but has an issue in Eclipse (Indigo).
Eclipse shows errors on @Convert(value = "Foo1Converter") as it thinks it can't find the named converters : "The specified converter "Foo1Converter" for mapping "foo1" cannot be resolved"

Everything however compiles and runs from eclipse or from the command line using maven. So this is more of a nuisance than anything else.
If we add a single @StructConverter then eclipse is happy, but then we can't seem to add multiple @StructConverter except in a @StructConverters collection. So we have to live with the errors.

Has anyone else seen such issues on Eclipse?
------------------------------------------------




[Updated on: Wed, 20 June 2012 15:39]

Report message to a moderator

Re: I need some help on adding StructConverters programatically. [message #891895 is a reply to message #889858] Tue, 26 June 2012 13:09 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Your first issue is that JPA defaults to serializing an object if it is not a basic type, and does not use a converter. Using the converter on it is the only way to avoid having JPA default to serializing it. You could process all of the mappings in the session and remove the SerializedObjectConverter from them if they are mapping your structured type. You will also need to set the mapping's fieldType to java.sql.Types.STRUCT.

For the Eclipse warning, you can just ignore this, it is incorrect. Please log a bug on Eclipse Dali to also consider StructConverters.




James : Wiki : Book : Blog : Twitter
Re: I need some help on adding StructConverters programatically. [message #892011 is a reply to message #891895] Tue, 26 June 2012 20:00 Go to previous message
Sumitro Palit is currently offline Sumitro Palit
Messages: 2
Registered: June 2012
Junior Member
Hi James,

Thanks a lot for the response.

My cue was your comment "You could process all of the mappings in the session and remove the SerializedObjectConverter from them if they are mapping your structured type." I was doing everything else but not setting the converter on the DirectToFieldMapping to null.

I had added a SessionEventListener and overrode preLogin() to register my struct converters with the DatabasePlatform before session login. I added code to go over the descriptors, identify the mappings for the structured types and set converter to null
and field type to java.sql.Types.STRUCT on the appropriate mappings. That solved my problem - now we can do away with the annotations.
public void preLogin(SessionEvent event) {
       
		DatabasePlatform dp = (DatabasePlatform) event.getSession()
				.getDatasourcePlatform();
		dp.addStructConverter(new Foo1Converter());
		dp.addStructConverter(new Foo2Converter());

		System.out.println("MySessionEventListener.preLogin() StructConverters- " + dp.getStructConverters());	
		
		// Iterate over the descriptors
		// Identify DirectToFieldMappings for our structured types
		// 	Set converter to null
		// 	Set field type to java.sql.Types.STRUCT

		Map<Class, ClassDescriptor> descriptorMap = event.getSession()
				.getDescriptors();
		Set<Entry<Class, ClassDescriptor>> entries = descriptorMap.entrySet();

		for (Entry<Class, ClassDescriptor> entry : entries) {

			Class cls = entry.getKey();
                        // getUserDefinedTypeMap = my refelction based method that creates a map of attribute name to java type based on a marker interface
			Map<String, Class> attributeTypeMap = getUserDefinedTypeMap(cls);

			ClassDescriptor desc = entry.getValue();

			Vector<DatabaseMapping> mappings = desc.getMappings();
			for (DatabaseMapping mapping : mappings) {

				if (mapping instanceof DirectToFieldMapping) {
					DirectToFieldMapping dfm = (DirectToFieldMapping) mapping;
					if (attributeTypeMap
							.containsKey(mapping.getAttributeName())) {
						// set the converter to null
						dfm.setConverter(null);
						// set the field type to STRUCT
						dfm.setFieldType(java.sql.Types.STRUCT);
					}

				}
			}

		}
}



About the Eclipse issue, I will enter a bug. The code is compiling and running and the StructConverters are kicking in and doing their job (debugged our converters and convertToObject and convertToStruct are working correctly.) With the other approach working we won't need it immediately but it will be good to have it solved.


Thanks,

Sumitro


[Updated on: Tue, 26 June 2012 22:39]

Report message to a moderator

Previous Topic:The collection of metamodel types is empty.
Next Topic:No Persistence provider
Goto Forum:
  


Current Time: Thu Sep 18 01:38:02 GMT 2014

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

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