users@glassfish.java.net

Re: [eclipselink-users] SessionCustomizer to modify/detect database platform: impossible

From: Tom Ware <tom.ware_at_oracle.com>
Date: Thu, 21 Feb 2013 09:52:41 -0500

A third workaround suggested by a colleague

- Use the eclipselink.metadata-source persistence unit property to point to a
custom class that extends org.eclipse.persistence.jpa.metadata.MetadataSourceAdapter

- In your class implement

   public Map<String, Object> getPropertyOverrides(Map<String, Object>
properties, ClassLoader classLoader, SessionLog log)

and in the case where you need to specify the new platform, add the
eclispelink.target-database property to that list.

   This method is called immediately before login and should provide you what
you need.

-Tom

On 21/02/2013 8:46 AM, Tom Ware wrote:
> Hi Laird,
>
> It looks like the use-case where you want auto-detection of database platform
> for all but a single platform is not well covered by the current code base. I
> see you've filed bug 401388 for this issue. The easiest way for us to address
> your specific issue is to make the isInformixOuterJoin flag a boolean on the
> InformixPlatform that could be set in your customizer, this could be done
> quickly, but would not help you for your 2.3.2 deployment.
>
> The possible workarounds I see are:
>
> 1. Pass the new platform as a property when your EntityManagerFactory is created
> 2. Try to override the auto-detection yourself. This would involve roughly the
> following steps
> - Use the eclipselink.target-database property in your persistence.xml to set
> a platform... Any platform. (this setting will make EclipseLink avoid it's own
> auto-detection code)
> - In a prelogin event use the code from our
> DatabaseSessionImpl.loginAndDetectDatasource method to use our auto-detection
> code and then override the InformixPlatform if it is detected. Here is the code
> as it exists. You could override the platformName if it was the InformixPlatform:
>
> --
> try {
> String vendorNameAndVersion =
> conn.getMetaData().getDatabaseProductName() +
> conn.getMetaData().getDatabaseMajorVersion();
> platformName =
> DBPlatformHelper.getDBPlatform(vendorNameAndVersion, getSessionLog());
> getLogin().setPlatformClassName(platformName);
> } catch (EclipseLinkException classNotFound) {
> if (platformName.indexOf("Oracle") != -1) {
> // If we are running against Oracle, it is possible
> that we are running in an environment where
> // the OracleXPlatform class can not be loaded. Try
> using OraclePlatform class before giving up
>
> getLogin().setPlatformClassName(OraclePlatform.class.getName());
> } else {
> throw classNotFound;
> }
> }
> --
>
> Sorry this is so involved.
>
> -Tom
>
> On 21/02/2013 1:43 AM, Laird Nelson wrote:
>> Is it possible to write a SessionCustomizer that jumps in early enough to
>> install a custom platform on a session, AND that is immune to the platform's
>> jettisoning of any installed platform upon initial login?
>>
>> One of the first things that DatabaseSessionImpl.java does is to set the
>> session's associated platform--conveniently installed by my session
>> customizer--to null. WTF.
>>
>> In other words, a SessionCustomizer that I've written happily installs a new
>> platform...which is then immediately overwritten by the core EclipseLink
>> innards. I see no way to prevent this overwriting.
>>
>> A SessionEventListener which activates after a postLogin() event that does the
>> same thing results in dozens of NullPointerExceptions from deep within
>> QuerySequence.java later on in the persistence unit lifecycle, so that's not an
>> option.
>>
>> Relevant StackOverflow question:
>> http://stackoverflow.com/questions/14899458/what-is-the-proper-way-to-have-a-user-authored-eclipselink-databaseplatform-subc
>>
>>
>> Best,
>> Laird
>>
>> --
>> http://about.me/lairdnelson
>>
>>
>> _______________________________________________
>> eclipselink-users mailing list
>> eclipselink-users_at_eclipse.org
>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>