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

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