Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Change table name at runtime(Is it possible to change a class table name at runtime?)
Change table name at runtime [message #537481] Wed, 02 June 2010 11:16 Go to next message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
Hi there,

I've got a bunch of .DBF files that share the same structure, say they're named SALES200X.DBF and then I've got a Java class:

@Table("SALES2001");
class Sale { ...}

Then, I'd like to be able to work with other years, so I'd need to change the Table Name EclipseLink goes for the data at runtime.

I've being googling around without luck, the best I found was about messing with class loaders...

Is there someway I could modify the Table Name for a class at runtime? (ie: when creating the EntityManagerFactory).

Cheers,
Marc
Re: Change table name at runtime [message #537714 is a reply to message #537481] Thu, 03 June 2010 09:03 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

You can change the name of a classes table using the descriptor API.

ClassDescriptor.setTablesNames() (or getTables().clear(), setTableName())

You can access the descriptors using a SessionCustomizer or DescriptorCustomizer or through accessing the EclipseLink Session from the EntityManager.

You can only change the tables until the session is initialized/connected.

You can also add new descriptors at runtime, but can only have one descriptor per class per session.

You might consider having a subclass of Sale per year, or dynamically define a new session/EntityManagerFactory for each year, or dynamically generate a subclass and descriptor per year. You may wish to investigate EclipseLink's dynamic support.


James : Wiki : Book : Blog : Twitter
Re: Change table name at runtime [message #537744 is a reply to message #537714] Thu, 03 June 2010 10:15 Go to previous messageGo to next message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
Thanks for the tips James, I'll take a look at it and search about EclipseLink Dynamic support!

James wrote on Thu, 03 June 2010 09:03
You can change the name of a classes table using the descriptor API.

You might consider having a subclass of Sale per year, or dynamically define a new session/EntityManagerFactory for each year, or dynamically generate a subclass and descriptor per year. You may wish to investigate EclipseLink's dynamic support.



The files are really named: XXXYYYY.DBF, I have a lot of XXX values, with lots of years for them, and I may not know the whole list until I run the program so I cannot have so much subclasses Smile

I'll investigate the other stuff. Thanks again!!
Re: Change table name at runtime [message #538444 is a reply to message #537714] Mon, 07 June 2010 12:06 Go to previous messageGo to next message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
James wrote on Thu, 03 June 2010 09:03

You can access the descriptors using a SessionCustomizer or DescriptorCustomizer or through accessing the EclipseLink Session from the EntityManager.



Hi again,

I've been reading about the EclipseLink Sessions (mostly that) but I'm still lost.

According to that I should define a new session in my sessions.xml (which I don't have) and It says I have "New > Session configuration" in Eclipse which I don't have ;\\

Is there any default session I can "get" without having a sessions.xml file?

Or, where's the New > Session Configuration option? I can't find any super-magic wizard to create my sessions.xml Smile

Thanks a lot,
Marc
Re: Change table name at runtime [message #538485 is a reply to message #537481] Mon, 07 June 2010 13:59 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Don't worry about sessions.xml, it is not used with JPA.

You can get a Session from an EclipseLink JpaEntityManager using getSession(), or using em.unwrap(Session.class).

You can add a SessionCustomizer to your persistence.xml using the "eclipselink.session.customizer" persistence unit property.



James : Wiki : Book : Blog : Twitter
Re: Change table name at runtime [message #538806 is a reply to message #538485] Tue, 08 June 2010 12:55 Go to previous messageGo to next message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
Thanks for replying so quickly.

When I try with getSession() or getDefaultSession() eclipse complains about not having sessions.xml file.

I don't have the "unwrap()" method, after Googling around it seems it's new in JPA 2.0? If so, I'm on Galileo, with EclipseLink 1.0

I've tried to install EclipseLink 2.0 in Galileo with no luck, so, can I avoid the sessions.xml file in EclipseLink 1? (or how can I get EclipseLink 2.0 into Galileo).

Thanks! Smile
Re: Change table name at runtime [message #539000 is a reply to message #538806] Wed, 09 June 2010 06:06 Go to previous messageGo to next message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
Ok, I got JPA 2.0 to work, and now everything works almost perfectly.

Current (relevant) code is:
// getEntityManagerFactory sets some properties and returns it.
EntityManagerFactory emf = getEntityManagerFactory();
em = emf.createEntityManager();	    
Session session = (Session) em.unwrap(Session.class);
session.getDescriptor(Apunte.class).getTables().clear();
session.getDescriptor(Apunte.class).setTableName("SALES2010");
session.getDescriptor(Cuenta.class).getTables().clear();
session.getDescriptor(Cuenta.class).setTableName("SALES2010");
return em;


From that point I can query the SALES2010 table, insert data and so on *as far as I don't use transactions*. It's a DBF so I do not really care, but to improve my knowledge. How can I fix the transaction stuff when getting the EntityManager? ie:

This doesn't work:
			em.getTransaction().begin();
			em.persist(apu);
			em.getTransaction().commit();


It tries to insert into "SALES" instead of "SALES2010" as if the session was ignored.

Anyway, the stuff I need works, so THANKS! Smile
Re: Change table name at runtime [message #540894 is a reply to message #539000] Thu, 17 June 2010 10:52 Go to previous messageGo to next message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
Aparently I spoke to early. It seems EclipseLink won't persist() anythin outside of transactions. Which means that I must run inside a begin() commit() block.

That rises the issue again then. I do de setTableName() stuff on the EntityManager, but the Transaction completely ignores it, and tries to INSERT the data into the wrong table.

How can I make the setTableName() affect the transaction?

Thanks,
Marc
Re: Change table name at runtime [message #540918 is a reply to message #537481] Thu, 17 June 2010 11:45 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

As I said, you should not change a descriptor's table names after login. It should be done before creating your EntityManagerFactory, such as in a SessionCustomizer. Since the descriptors are shared across all EntityManagers, changing them on the fly is a bad idea.

You could unprepare the descriptor's insertQuery (from its DescriptorQueryManager) to get the insert to reprepare the SQL with the new table name. But changing descriptors on the fly is not a good idea.

You could try creating an entire new EntityManagerFactory on the fly with the new descriptor, or create a subclass for each table and clone the descriptor to map the subclass with the new table, or investigate EclipseLink dynamic Entity support.


James : Wiki : Book : Blog : Twitter
Re: Change table name at runtime [message #541108 is a reply to message #540918] Fri, 18 June 2010 07:40 Go to previous message
Marc Fargas is currently offline Marc Fargas
Messages: 22
Registered: May 2010
Junior Member
Sorry, I misread your first reply and understood I *should NOT* do anything before getting the manager. I reread the thread Smile

Anyway, I got it working with the transactions and all that using a SessionCustomizer.

My final solution:

* When I create my EntityManagerFactory I set an additional property to it: "myproject.sales_year"

* In my SessionCustomizer I get this property and then do a:
session.getDescriptor(Sales.class).getTable("SALES").setName( "SALES"+year);

That seems to work.

Thanks for all the help!
Previous Topic:support for MaxDB 7.6.x?
Next Topic:using EclipseLink in an Eclipse rich client plugin
Goto Forum:
  


Current Time: Tue Jul 22 09:37:29 EDT 2014

Powered by FUDForum. Page generated in 0.03369 seconds