Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Postgresql and UUID eclipselink 2.4.0

Hi Edward,

finally I've found some time to update my code and integrate the UUIDConverter.

The current releases support the following PostgreSQL types:
* uuid
* cidr
* inet
* macaddr

Please have a look at it and say if you have any problems using it:

For the PostgreSQL 8.x driver:
https://oss.sonatype.org/content/repositories/releases/org/ancoron/postgresql/org.ancoron.postgresql.jpa/8.4.702.jdbc4.1-rc4/

For the PostgreSQL 9.x driver:
https://oss.sonatype.org/content/repositories/releases/org/ancoron/postgresql/org.ancoron.postgresql.jpa/9.1.901.jdbc4.1-rc6/

I've also integrated support for mapping those data types without requiring the developer to use provider-specific stuff inside the application code:

https://github.com/ancoron/pg-inet-maven/wiki/Support-custom-data-types-in-EclipseLink

(scroll down to "SessionEventListener")

You'll find setup instructions in the README here:

https://github.com/ancoron/pg-inet-maven

Cheers,

	Ancoron


On 08/13/2012 07:48 PM, Edward Mann wrote:
On Mon, 2012-08-13 at 07:45 +0200, Ancoron Luciferis wrote:
On 08/11/2012 09:56 PM, Edward Mann wrote:
On Fri, 2012-08-10 at 13:30 +0200, Ancoron Luciferis wrote:
On 08/10/2012 04:57 AM, Edward Mann wrote:
I am not sure what performance penalties if any this will introduce, but
this is how i got the uuid to work. I wanted to send this out so anyone
else having this issue can try this, and also get feedback on if this is
not a good thing to do.

I changed all the UUID to String and made the following two changes to
the persistent.xml file

for postgresql i am able to use ?stringtype=unspecified in the url for
the database connection.
Also i had to add
<property name="eclipselink.jdbc.bind-parameters" value="false" />
to the properties section. With both of those things are working as
expected. Granted all my tables are small so i might be in for a
surprise.

Thanks for your input everyone.

Hi Edward,

glad to hear you got it working. But when you don't let EclipseLink bind
the parameters I think it may affect performance quite a lot, see here:

http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/q_bindparameters.htm

So, I think you're better off with a converter. I've done this for the
inet extension of PostgreSQL for different mappings, e.g.
java.net.InetAddress:

https://github.com/ancoron/pg-inet-maven/blob/master/org.ancoron.postgresql.jpa/src/main/java/org/ancoron/postgresql/jpa/eclipselink/InetAddressConverter.java

However, in case of UUID the PostgreSQL driver already is able to map
java.lang.UUID to the internal uuid type for JDBC-3g and JDBC-4 connections:

class AbstractJdbc3gStatement:

import java.sql.*;
import java.util.UUID;

import org.postgresql.core.Oid;
...
public void setObject(int parameterIndex, Object x) throws SQLException
{
       if (x instanceof UUID && connection.haveMinimumServerVersion("8.3"))
       {
           setString(parameterIndex, x.toString(), Oid.UUID);
       } else {
           super.setObject(parameterIndex, x);
       }
}

So your converter may just pass the java.lang.UUID object in and out -
no conversion required at all.

Cheers,

	Ancoron


On Tue, 2012-08-07 at 09:16 +0200, Ancoron Luciferis wrote:
Hi Edward,

I think you need to either:

1.) provide a custom converter (UUID (java) <-> UUID (PostgreSQL))

2.) provide an custom type mapping


...for 1.) there are enough information out there on the EclipseLink
wiki, for 2.) there is almost no information how to code that, as I
still have the same problem with other types.

Cheers,

	Ancoron


On 08/06/2012 07:11 PM, Edward Mann wrote:
I have been trying to figure out how to get the native uuid type in
            postgresql and eclipselink to work together. I have a simple
table for
            testing:

            CREATE TABLE elink
            (
              el_id uuid NOT NULL DEFAULT uuid_generate_v4(), -- elink id
              el_name character varying(255), -- elink name
              CONSTRAINT el_pkey PRIMARY KEY (el_id )
              DEFERRABLE INITIALLY IMMEDIATE
            )
            WITH (
              OIDS=FALSE
            );
            ALTER TABLE elink
            OWNER TO emann;
            COMMENT ON COLUMN elink.el_id IS 'elink id';
            COMMENT ON COLUMN elink.el_name IS 'elink name';


            And the annotation on the field for id is:

            @Id
                    @Column(name="el_id")
                    @UuidGenerator(name="uuid")
                    @GeneratedValue(generator="uuid")
                    private UUID elId;

            I have also tried the custom UUIDSequence mentioned on the
website,
            however that did not work either. I get the following error
(this is the
            UUIDSequence native to 2.4.0):

            Exception [EclipseLink-3002] (Eclipse Persistence Services -
            2.4.0.v20120608-r11652):
            org.eclipse.persistence.exceptions.ConversionException
            Exception Description: The object
            [66FB2FFB-2735-4A8C-AFDE-19246C78CC16], of class [class
            java.lang.String], from mapping

[org.eclipse.persistence.mappings.DirectToFieldMapping[elId-->ELINK.el_id]] with descriptor [RelationalDescriptor(model.Elink --> [DatabaseTable(ELINK)])], could not be converted to [class [B].


            So i am really curious about what is the proper way to get this
to work
            using uuid type in postgresql.
            Any help is welcome, thanks in advance.

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users






Thank you for the advice Ancoron, i read over your what you wrote and
also looked at the code you posted a link for. This is what i have
implemented based on what i read and know.

I changed my persistent.xml to remove the stringtype=unspecified and
also the <property name="eclipselink.jdbc.bind-parameters"
value="false" /> i removed as well.

And here is the UUIDConverter class i wrote.

package org.ledger.core;

import java.util.UUID;

import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;

/**
   * Supports mapping of <tt>java.util.UUID</tt> inside JPA entities.
   *
   * <p>
   * Example usage:
   * <pre>
   * //..
   * import java.util.UUID;
   * import org.ledger.core.UUIDConverter;
   *  //..
   *
   *  &#064;Entity
   *
&#064;Converter(name="uuidConverter",converterCalss=UUIDConverter.class)
   *  public class Elink implements Serializable {
   *  	 &#064;Convert("uuidConverter")
   * 	 &#064;Column(name="elink_id")
   * 	 private UUID elinkId;
   *   //..
   *   }
   *   </pre>
   *   </p>
   *
   * @author Edward Mann
   * @see
https://github.com/ancoron/pg-inet-maven/blob/master/org.ancoron.postgresql.jpa/src/main/java/org/ancoron/postgresql/jpa/eclipselink/InetAddressConverter.java
   * @see
http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg07359.html
   */
public class UUIDConverter implements Converter {

      /**
       *
       */
      private static final long serialVersionUID = -8738182233279166782L;

      @Override
      public Object convertObjectValueToDataValue(Object objectValue,
	    Session session) {
	return objectValue;
      }

      @Override
      public UUID convertDataValueToObjectValue(Object dataValue,
	    Session session) {
		return (UUID)dataValue;
      }

      @Override
      public boolean isMutable() {
	return true;
      }

      @Override
      public void initialize(DatabaseMapping mapping, Session session) {
	final DatabaseField field;
          if(mapping instanceof DirectCollectionMapping) {
              // handle @ElementCollection...
              field = ((DirectCollectionMapping)
mapping).getDirectField();
          } else
              field = mapping.getField();

          field.setSqlType(java.sql.Types.OTHER);
          field.setTypeName("uuid");
          field.setColumnDefinition("UUID");
      }
}


I ran it on my little test table and everything is working as expected.
If you see anything i should update let me know, or anyone else for that
matter.

Thanks again for your input and direction, i really appreciate it.


Hi Edward,

Glad that worked out that nice. :)


I would like to include that converter into my project hosted at github
in a separate artifact for others to use in their application projects.

You would, of course, stay the author of this converter and I will
notify you of bugfixes or enhancements (if there are any).

Please tell me if this would be fine for you and which license you would
like to contribute this. Btw. I'm usually using the Apache 2.


Cheers,

	Ancoron


Yes you can include it, and since i took from your Converter you can use
the license that you prefer. I posted it to the list so others could use
it as well, so you including it in you project accomplishes my goal.

If i come across any issues while i use it and need to fix bugs i will
notify you.

Thanks.




Back to the top