[
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 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;
* //..
*
* @Entity
*
@Converter(name="uuidConverter",converterCalss=UUIDConverter.class)
* public class Elink implements Serializable {
* @Convert("uuidConverter")
* @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.