• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Spring/JPA/TopLink 11g extensions

 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

Im currently trying to use Spring/JPA with some TopLink 11g extensions for Conversion but are unable to get this working.
I have tried a lot of different converters but it seems like all my TopLink annotations are ignored.

I would really appriciate all help I can get on this.

Iv included a small "dummy" below.

When using the converter on the class below I was hoping that the generated schema would be like:

CREATE TABLE TYPECONVTEST (ID NUMERIC(19) NOT NULL, AGE VARCHAR2(255), PRIMARY KEY (ID))

But the generated schema is:

CREATE TABLE TYPECONVTEST (ID NUMERIC(19) NOT NULL, AGE INTEGER, PRIMARY KEY (ID))


Dummy example:



My Spring configuration is like this:

 
author
Posts: 304
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Rune,

Why you are using a type converter if you are generating the schema. Why not just use an int on both sides? Converters are normally used for mapping an object model to a pre-existing legacy database, not when you have the choice to generate a schema.

If you are in a situation (either because you are just performing testing, or for whatever other reason the database you are generating needs to map an int in the object model to a string in the data model then you should be able to use the @Column annotation to explicitly dictate the column to get generated. For example:

@Convert("intToString")
@Column(name="AGE", columnDefinition="VARCHAR2(255)")
int age;
 
Rune Kvamme
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mike,

Thank you for your answer. I realize that the example Iv included was a bit to simple. It was just to illustrate that I did not manage to get any of the Oracle TopLink extensions annotations to work properly.

What Im really trying to do is to write a converter that converts the Eric Evans Time&money library class com.domainlanguage.time.CalendarDate. The CalendarDate class consist of three properties, i.e. year, month and day, which I want to persist as a date column in the database.

We could use embeddable, but this will not be possible due to the JPA limitation with embeddables (embeddable within embeddable).

Im really was hoping that the new feature in TopLink 11g would help me.

BTW. Iv managed to do this with TopLink essentials using a session custimizer, but I really would like to use the annotation style.

public class ConverterCustomizer implements SessionCustomizer {



Best regards,
Rune
 
Mike Keith
author
Posts: 304
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, so your real problem is simply that your annotations don't appear to be getting recognized? I can only think of a few things that could be causing that. Either your class is not being discovered (i.e. it is not packaged in a place where discovery is occurring) or it is not annotated as an entity. Other than that it could only be a configuration error (TopLink not being invoked for that entity, etc).

You can turn logging on to debug mode to see the entities it is finding. Do this by setting your logging property to "FINEST". I have noticed that the Spring "showSQL" property seems to hammer whatever the provider logging property is set to, so you need to remove the Spring property in order to set the logging to any other mode than FINE.
 
Rune Kvamme
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mike,

Thank you for taking interest in my issue.

I have set the logging level to FINEST and can see that my entity class is discovered and that a table is created.

--CREATE TABLE CUSTOMER (ID NUMERIC(19) NOT NULL, AGE NUMERIC(38), CALENDARDATE BINARY, PRIMARY KEY (ID))

The table is however not as expected as the converter annotations are not discovered. Im running the test as a JUnit test and have event tried to set a breakpoint in the converter class. It does not break.

I did however make a small test using a standalone Java application without Spring. Then the converter annotations was discovered and the create table statement was as expected.

--CREATE TABLE CUSTOMER (ID NUMERIC(19) NOT NULL, AGE VARCHAR(255), CALENDARDATE DATE, PRIMARY KEY (ID))

My conclusion is that it must have something to do with my Spring configuration. Could it have something do with not using the oracle.toplink.ejb.cmp3.EntityManagerFactoryProvider directly as I do in the standalone application?

I have included the not working example and my Spring configuration below.

Many thanks
Rune

Entity class



applicationContext.xml



persistence.xml



orm.xml

I have removed this file since Im only using annotations.
 
Mike Keith
author
Posts: 304
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Rune,

DDL generation occurs through a slightly different path in a container than when using the factory API. One possibility is that the TopLink annotations are not recognized in the Container scenario until after the generation. You can test this out in one of two ways.

You can use the Column annotation to cause the correct column type to be generated and then run a few tests that will test whether the types get converted at runtime (if they do then the annotations were indeed detected, they just weren't used at generation-time).

Another thing to try is to change the Spring factory bean to be a LocalEntityManagerFactoryBean instead of a LocalContainerEntityManagerFactoryBean. This will cause Spring to use the regular factory API instead of the special container API and you can compare the results.
 
Ranch Hand
Posts: 553
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Make sure you are using TopLink 11g, not TopLink Essentials in your Spring server. You should see the TopLink version printed in your TopLink log, does it say 11g or Essentials?
 
Rune Kvamme
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I tried to use the LocalEntityManagerFactoryBean and then the annotations was detected. The log below shows that the default serialization is ignored due to the @Convert annotation.


TopLink Finest]: 2007.11.14 03:34:01.077--ServerSession(32486590)--Thread(Thread[main,5,main])--property=toplink.orm.throw.exceptions; default value=true
[TopLink Finer]: 2007.11.14 03:34:01.077--ServerSession(32486590)--Thread(Thread[main,5,main])--Searching for default mapping file in file:/C:/devtools/NG/eclipse/workspace/JpaTestProject%20-%20TopLink%2011g/target/classes/
[TopLink Config]: 2007.11.14 03:34:01.280--ServerSession(32486590)--Thread(Thread[main,5,main])--The alias name for the entity class [class com.statoil.sas.invpilot.customer.domain.Customer] is being defaulted to: Customer.
[TopLink Config]: 2007.11.14 03:34:01.280--ServerSession(32486590)--Thread(Thread[main,5,main])--The table name for entity [class com.statoil.sas.invpilot.customer.domain.Customer] is being defaulted to: CUSTOMER.
[TopLink Config]: 2007.11.14 03:34:01.312--ServerSession(32486590)--Thread(Thread[main,5,main])--The column name for element [private long com.statoil.sas.invpilot.customer.domain.Customer.id] is being defaulted to: ID.
[TopLink Config]: 2007.11.14 03:34:01.343--ServerSession(32486590)--Thread(Thread[main,5,main])--The column name for element [private java.lang.Number com.statoil.sas.invpilot.customer.domain.Customer.age] is being defaulted to: AGE.
[TopLink Warning]: 2007.11.14 03:34:01.343--ServerSession(32486590)--Thread(Thread[main,5,main])--Ignoring default serialization on element [private java.lang.Number com.statoil.sas.invpilot.customer.domain.Customer.age] within entity class [class com.statoil.sas.invpilot.customer.domain.Customer] since a @Convert is specified.



Then, when using the LocalContainerEntityManagerFactoryBean I get the following log. As you can see, there is no indication of any Converters:-(




As you can see Im using TopLink 11g. Have any of you tried using toplink 11g annotations successfully with Spring LocalContainerEntityManagerFactoryBean?

Still struggling and hoping:-)

Best regards,
Rune
 
James Sutherland
Ranch Hand
Posts: 553
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Very odd, the only thing I can think of is that you are deploying different code somehow with the Container deployment. Try changing something else in the class and see if it is picked up.

If still no luck, try other annotations add see if they have the same issue.
 
Rune Kvamme
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi James,

I have tried to use several different annotations and have also changed different parts of the entity. It all results in the same, TopLink annotations not beeing discovered when using the LocalContainerEntityManagerFactoryBean and not discovered when using the LocalEntityManagerFactoryBean.

Im not really deploying to a server as Im running it withing Eclipse. Could that be a problem?

Is it at all possible that this is a bug?

Have you tried this before? Do you have any working examples?

I could of course email you my test project, but I guess you are to busy to test it, or?:-)

Many thanks,
Rune
 
Rune Kvamme
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi again,

Another question,

Is it possible to configure a converter using an alternative approach?
I know it is possible using a session customizer, but is it possible to configure this in the orm.xml?

Best regards,
Rune
 
Mike Keith
author
Posts: 304
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Rune,

I think there actually is a problem with using Container API in Spring with TopLink-specific annotations. I tried it out and the container classloader in Spring loads them in a different classloader than what is expected. I could give you a patch for the Spring classloader class, but if you are not running in a server then you may as well just use the LocalEntityManagerFactoryBean. You are not losing anything at all, and you would just need to specify the TopLink agent jar when you start the application and you would get all the weaving, etc.
 
Rune Kvamme
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mike,

Thank you very much, I really appriciate your help. We will be running our applications within a container, its just for testing purposes I have been running outside the container.

If you could supply me with at a patch for the Spring class loader I would be very greatful. Is this a bug in Spring or TopLink? Do you think it will will be fixed?

Many thanks:-)

Best regards,
Rune
 
Mike Keith
author
Posts: 304
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rune,

I wouldn't really consider it a bug in either Spring or TopLink, since both are actually correctly fulfilling their roles as Container and Provider using the SPI. The problem seems to be a side-effect of a few things mixed together. We will have to get together with the Spring guys and work out the best way to fix it long-term. The simplest fix is to put some code in the Spring classloader, but that might not be the best long-term solution. I will send you the patch.
reply
    Bookmark Topic Watch Topic
  • New Topic