HHH-5268 - Support for java.util.UUID properties/generators
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19646 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
41b2416be4
commit
7aa8449788
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
* distributed under license by Red Hat Inc.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
@ -20,7 +20,6 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id;
|
package org.hibernate.id;
|
||||||
|
|
||||||
|
@ -41,8 +40,19 @@ import org.hibernate.exception.JDBCExceptionHelper;
|
||||||
* @author Joseph Fifield
|
* @author Joseph Fifield
|
||||||
*/
|
*/
|
||||||
public class GUIDGenerator implements IdentifierGenerator {
|
public class GUIDGenerator implements IdentifierGenerator {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(GUIDGenerator.class);
|
private static final Logger log = LoggerFactory.getLogger(GUIDGenerator.class);
|
||||||
|
private static boolean warned = false;
|
||||||
|
|
||||||
|
public GUIDGenerator() {
|
||||||
|
if ( ! warned ) {
|
||||||
|
warned = true;
|
||||||
|
log.warn(
|
||||||
|
"DEPRECATED : use {} instead with custom {} implementation",
|
||||||
|
UUIDGenerator.class.getName(),
|
||||||
|
UUIDGenerationStrategy.class.getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Serializable generate(SessionImplementor session, Object obj)
|
public Serializable generate(SessionImplementor session, Object obj)
|
||||||
throws HibernateException {
|
throws HibernateException {
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.id;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A strategy for generating a variant 2 {@link UUID} value.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface UUIDGenerationStrategy extends Serializable {
|
||||||
|
/**
|
||||||
|
* Which variant, according to IETF RFC 4122, of UUID does this strategy generate? RFC 4122 defines
|
||||||
|
* 5 variants (though it only describes algorithms to generate 4):<ul>
|
||||||
|
* <li>1 = time based</li>
|
||||||
|
* <li>2 = DCE based using POSIX UIDs</li>
|
||||||
|
* <li>3 = name based (md5 hash)</li>
|
||||||
|
* <li>4 = random numbers based</li>
|
||||||
|
* <li>5 = name based (sha-1 hash)</li>
|
||||||
|
* </ul>
|
||||||
|
* Returning the values above should be reserved to those generators creating variants compliant with the
|
||||||
|
* corresponding RFC definition; others can feel free to return other values as they see fit.
|
||||||
|
* <p/>
|
||||||
|
* Informational only, and not used at this time.
|
||||||
|
*
|
||||||
|
* @return The supported generation version
|
||||||
|
*/
|
||||||
|
public int getGeneratedVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the UUID.
|
||||||
|
*
|
||||||
|
* @param session The session asking for the generation
|
||||||
|
*
|
||||||
|
* @return The generated UUID.
|
||||||
|
*/
|
||||||
|
public UUID generateUUID(SessionImplementor session);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.id;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.id.uuid.StandardRandomStrategy;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
|
||||||
|
import org.hibernate.util.ReflectHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link IdentifierGenerator} which generates {@link UUID} values using a pluggable
|
||||||
|
* {@link UUIDGenerationStrategy generation strategy}. The values this generator can return
|
||||||
|
* include {@link UUID}, {@link String} and byte[16]
|
||||||
|
* <p/>
|
||||||
|
* Supports 2 config parameters:<ul>
|
||||||
|
* <li>{@link #UUID_GEN_STRATEGY} - names the {@link UUIDGenerationStrategy} instance to use</li>
|
||||||
|
* <li>{@link #UUID_GEN_STRATEGY_CLASS} - names the {@link UUIDGenerationStrategy} class to use</li>
|
||||||
|
* </ul>
|
||||||
|
* <p/>
|
||||||
|
* Currently there are 2 standard implementations of {@link UUIDGenerationStrategy}:<ul>
|
||||||
|
* <li>{@link StandardRandomStrategy} (the default, if none specified)</li>
|
||||||
|
* <li>{@link org.hibernate.id.uuid.CustomVersionOneStrategy}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UUIDGenerator implements IdentifierGenerator, Configurable {
|
||||||
|
public static final String UUID_GEN_STRATEGY = "uuid_gen_strategy";
|
||||||
|
public static final String UUID_GEN_STRATEGY_CLASS = "uuid_gen_strategy_class";
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( UUIDGenerator.class );
|
||||||
|
|
||||||
|
private UUIDGenerationStrategy strategy;
|
||||||
|
private UUIDTypeDescriptor.ValueTransformer valueTransformer;
|
||||||
|
|
||||||
|
public void configure(Type type, Properties params, Dialect d) throws MappingException {
|
||||||
|
// check first for the strategy instance
|
||||||
|
strategy = (UUIDGenerationStrategy) params.get( UUID_GEN_STRATEGY );
|
||||||
|
if ( strategy == null ) {
|
||||||
|
// next check for the strategy class
|
||||||
|
final String strategyClassName = params.getProperty( UUID_GEN_STRATEGY_CLASS );
|
||||||
|
if ( strategyClassName != null ) {
|
||||||
|
try {
|
||||||
|
final Class strategyClass = ReflectHelper.classForName( strategyClassName );
|
||||||
|
try {
|
||||||
|
strategy = (UUIDGenerationStrategy) strategyClass.newInstance();
|
||||||
|
}
|
||||||
|
catch ( Exception ignore ) {
|
||||||
|
log.warn( "Unable to instantiate UUID generation strategy class : {}", ignore );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( ClassNotFoundException ignore ) {
|
||||||
|
log.warn( "Unable to locate requested UUID generation strategy class : {}", strategyClassName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( strategy == null ) {
|
||||||
|
// lastly use the standard random generator
|
||||||
|
strategy = StandardRandomStrategy.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( UUID.class.isAssignableFrom( type.getReturnedClass() ) ) {
|
||||||
|
valueTransformer = UUIDTypeDescriptor.PassThroughTransformer.INSTANCE;
|
||||||
|
}
|
||||||
|
else if ( String.class.isAssignableFrom( type.getReturnedClass() ) ) {
|
||||||
|
valueTransformer = UUIDTypeDescriptor.ToStringTransformer.INSTANCE;
|
||||||
|
}
|
||||||
|
else if ( byte[].class.isAssignableFrom( type.getReturnedClass() ) ) {
|
||||||
|
valueTransformer = UUIDTypeDescriptor.ToBytesTransformer.INSTANCE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new HibernateException( "Unanticipated return type [" + type.getReturnedClass().getName() + "] for UUID conversion" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
|
||||||
|
return valueTransformer.transform( strategy.generateUUID( session ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
* distributed under license by Red Hat Inc.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
@ -20,14 +20,15 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.id;
|
package org.hibernate.id;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.Hibernate;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.SessionImplementor;
|
import org.hibernate.engine.SessionImplementor;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -45,54 +46,54 @@ import org.hibernate.util.PropertiesHelper;
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class UUIDHexGenerator extends AbstractUUIDGenerator implements Configurable {
|
public class UUIDHexGenerator extends AbstractUUIDGenerator implements Configurable {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( UUIDHexGenerator.class );
|
||||||
|
private static boolean warned = false;
|
||||||
|
|
||||||
private String sep = "";
|
private String sep = "";
|
||||||
|
|
||||||
protected String format(int intval) {
|
public UUIDHexGenerator() {
|
||||||
String formatted = Integer.toHexString(intval);
|
if ( ! warned ) {
|
||||||
StringBuffer buf = new StringBuffer("00000000");
|
warned = true;
|
||||||
buf.replace( 8-formatted.length(), 8, formatted );
|
log.warn(
|
||||||
return buf.toString();
|
"Using {} which does not generate IETF RFC 4122 compliant UUID values; consider using {} instead",
|
||||||
|
this.getClass().getName(),
|
||||||
|
UUIDGenerator.class.getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String format(short shortval) {
|
/**
|
||||||
String formatted = Integer.toHexString(shortval);
|
* {@inheritDoc}
|
||||||
StringBuffer buf = new StringBuffer("0000");
|
*/
|
||||||
buf.replace( 4-formatted.length(), 4, formatted );
|
public void configure(Type type, Properties params, Dialect d) {
|
||||||
return buf.toString();
|
sep = PropertiesHelper.getString( "separator", params, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Serializable generate(SessionImplementor session, Object obj) {
|
public Serializable generate(SessionImplementor session, Object obj) {
|
||||||
return new StringBuffer(36)
|
return new StringBuffer( 36 )
|
||||||
.append( format( getIP() ) ).append(sep)
|
.append( format( getIP() ) ).append( sep )
|
||||||
.append( format( getJVM() ) ).append(sep)
|
.append( format( getJVM() ) ).append( sep )
|
||||||
.append( format( getHiTime() ) ).append(sep)
|
.append( format( getHiTime() ) ).append( sep )
|
||||||
.append( format( getLoTime() ) ).append(sep)
|
.append( format( getLoTime() ) ).append( sep )
|
||||||
.append( format( getCount() ) )
|
.append( format( getCount() ) )
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configure(Type type, Properties params, Dialect d) {
|
protected String format(int intValue) {
|
||||||
sep = PropertiesHelper.getString("separator", params, "");
|
String formatted = Integer.toHexString( intValue );
|
||||||
|
StringBuffer buf = new StringBuffer( "00000000" );
|
||||||
|
buf.replace( 8 - formatted.length(), 8, formatted );
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main( String[] args ) throws Exception {
|
protected String format(short shortValue) {
|
||||||
Properties props = new Properties();
|
String formatted = Integer.toHexString( shortValue );
|
||||||
props.setProperty("separator", "/");
|
StringBuffer buf = new StringBuffer( "0000" );
|
||||||
IdentifierGenerator gen = new UUIDHexGenerator();
|
buf.replace( 4 - formatted.length(), 4, formatted );
|
||||||
( (Configurable) gen ).configure(Hibernate.STRING, props, null);
|
return buf.toString();
|
||||||
IdentifierGenerator gen2 = new UUIDHexGenerator();
|
|
||||||
( (Configurable) gen2 ).configure(Hibernate.STRING, props, null);
|
|
||||||
|
|
||||||
for ( int i=0; i<10; i++) {
|
|
||||||
String id = (String) gen.generate(null, null);
|
|
||||||
System.out.println(id);
|
|
||||||
String id2 = (String) gen2.generate(null, null);
|
|
||||||
System.out.println(id2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
|
import org.hibernate.id.UUIDGenerator;
|
||||||
import org.hibernate.id.UUIDHexGenerator;
|
import org.hibernate.id.UUIDHexGenerator;
|
||||||
import org.hibernate.id.TableHiLoGenerator;
|
import org.hibernate.id.TableHiLoGenerator;
|
||||||
import org.hibernate.id.Assigned;
|
import org.hibernate.id.Assigned;
|
||||||
|
@ -65,7 +66,10 @@ public class DefaultIdentifierGeneratorFactory implements IdentifierGeneratorFac
|
||||||
* Constructs a new DefaultIdentifierGeneratorFactory.
|
* Constructs a new DefaultIdentifierGeneratorFactory.
|
||||||
*/
|
*/
|
||||||
public DefaultIdentifierGeneratorFactory() {
|
public DefaultIdentifierGeneratorFactory() {
|
||||||
register( "uuid", UUIDHexGenerator.class );
|
register( "uuid2", UUIDGenerator.class );
|
||||||
|
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
|
||||||
|
register( "uuid", UUIDHexGenerator.class ); // "deprecated" for new use
|
||||||
|
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
|
||||||
register( "hilo", TableHiLoGenerator.class );
|
register( "hilo", TableHiLoGenerator.class );
|
||||||
register( "assigned", Assigned.class );
|
register( "assigned", Assigned.class );
|
||||||
register( "identity", IdentityGenerator.class );
|
register( "identity", IdentityGenerator.class );
|
||||||
|
@ -74,8 +78,6 @@ public class DefaultIdentifierGeneratorFactory implements IdentifierGeneratorFac
|
||||||
register( "seqhilo", SequenceHiLoGenerator.class );
|
register( "seqhilo", SequenceHiLoGenerator.class );
|
||||||
register( "increment", IncrementGenerator.class );
|
register( "increment", IncrementGenerator.class );
|
||||||
register( "foreign", ForeignGenerator.class );
|
register( "foreign", ForeignGenerator.class );
|
||||||
register( "guid", GUIDGenerator.class );
|
|
||||||
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
|
|
||||||
register( "sequence-identity", SequenceIdentityGenerator.class );
|
register( "sequence-identity", SequenceIdentityGenerator.class );
|
||||||
register( "enhanced-sequence", SequenceStyleGenerator.class );
|
register( "enhanced-sequence", SequenceStyleGenerator.class );
|
||||||
register( "enhanced-table", TableGenerator.class );
|
register( "enhanced-table", TableGenerator.class );
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.id.uuid;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.id.UUIDGenerationStrategy;
|
||||||
|
import org.hibernate.util.BytesHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a version 1 (time-based) generation strategy (using ip address rather than mac address) but applies them in a
|
||||||
|
* different layout. The strategy is very similar to the legacy {@link org.hibernate.id.UUIDHexGenerator} id generator
|
||||||
|
* but uses a RFC 4122 compliant layout (variant 2).
|
||||||
|
* <p/>
|
||||||
|
* NOTE : Can be a bottle neck due to the need to synchronize in order to increment an
|
||||||
|
* internal count as part of the algorithm.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class CustomVersionOneStrategy implements UUIDGenerationStrategy {
|
||||||
|
public int getGeneratedVersion() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final long mostSignificantBits;
|
||||||
|
|
||||||
|
public CustomVersionOneStrategy() {
|
||||||
|
// generate the "most significant bits" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
byte[] hiBits = new byte[8];
|
||||||
|
// use address as first 32 bits (8 * 4 bytes)
|
||||||
|
System.arraycopy( Helper.getAddressBytes(), 0, hiBits, 0, 4 );
|
||||||
|
// use the "jvm identifier" as the next 32 bits
|
||||||
|
System.arraycopy( Helper.getJvmIdentifierBytes(), 0, hiBits, 4, 4 );
|
||||||
|
// set the version (rfc term) appropriately
|
||||||
|
hiBits[6] &= 0x0f;
|
||||||
|
hiBits[6] |= 0x10;
|
||||||
|
|
||||||
|
mostSignificantBits = BytesHelper.asLong( hiBits );
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID generateUUID(SessionImplementor session) {
|
||||||
|
long leastSignificantBits = generateLeastSignificantBits( System.currentTimeMillis() );
|
||||||
|
return new UUID( mostSignificantBits, leastSignificantBits );
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMostSignificantBits() {
|
||||||
|
return mostSignificantBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long generateLeastSignificantBits(long seed) {
|
||||||
|
byte[] loBits = new byte[8];
|
||||||
|
|
||||||
|
short hiTime = (short) ( seed >>> 32 );
|
||||||
|
int loTime = (int) seed;
|
||||||
|
System.arraycopy( BytesHelper.fromShort( hiTime ), 0, loBits, 0, 2 );
|
||||||
|
System.arraycopy( BytesHelper.fromInt( loTime ), 0, loBits, 2, 4 );
|
||||||
|
System.arraycopy( Helper.getCountBytes(), 0, loBits, 6, 2 );
|
||||||
|
loBits[0] &= 0x3f;
|
||||||
|
loBits[0] |= ((byte)2 << (byte)6);
|
||||||
|
|
||||||
|
return BytesHelper.asLong( loBits );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
CustomVersionOneStrategy strategy = new CustomVersionOneStrategy();
|
||||||
|
|
||||||
|
for ( int i = 0; i < 1000; i++ ) {
|
||||||
|
System.out.println( "Generation # " + i + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
byte[] loBits = new byte[8];
|
||||||
|
|
||||||
|
long sysTime = System.currentTimeMillis();
|
||||||
|
short hiTime = (short) ( System.currentTimeMillis() >>> 32 );
|
||||||
|
int loTime = (int) sysTime;
|
||||||
|
System.arraycopy( BytesHelper.fromShort( hiTime ), 0, loBits, 0, 2 );
|
||||||
|
System.arraycopy( BytesHelper.fromInt( loTime ), 0, loBits, 2, 4 );
|
||||||
|
System.arraycopy( Helper.getCountBytes(), 0, loBits, 6, 2 );
|
||||||
|
|
||||||
|
System.out.println( " before bit setting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
System.out.println( " loBits[0] : " + BytesHelper.toBinaryString( loBits[0] ) );
|
||||||
|
System.out.println( " lsb : " + BytesHelper.toBinaryString( BytesHelper.asLong( loBits ) ) );
|
||||||
|
System.out.println( " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
|
||||||
|
loBits[0] &= 0x3f;
|
||||||
|
loBits[0] |= ((byte)2 << (byte)6);
|
||||||
|
|
||||||
|
System.out.println( " after bit setting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
System.out.println( " loBits[0] : " + BytesHelper.toBinaryString( loBits[0] ) );
|
||||||
|
long leastSignificantBits = BytesHelper.asLong( loBits );
|
||||||
|
System.out.println( " lsb : " + BytesHelper.toBinaryString( leastSignificantBits ) );
|
||||||
|
System.out.println( " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
|
||||||
|
|
||||||
|
UUID uuid = new UUID( strategy.mostSignificantBits, leastSignificantBits );
|
||||||
|
System.out.println( " uuid : " + uuid.toString() );
|
||||||
|
System.out.println( " variant : " + uuid.variant() );
|
||||||
|
System.out.println( " version : " + uuid.version() );
|
||||||
|
if ( uuid.variant() != 2 ) {
|
||||||
|
throw new RuntimeException( "bad variant" );
|
||||||
|
}
|
||||||
|
System.out.println( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.id.uuid;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import org.hibernate.util.BytesHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class Helper {
|
||||||
|
|
||||||
|
// IP ADDRESS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
private static final byte[] ADDRESS_BYTES;
|
||||||
|
private static final int ADDRESS_INT;
|
||||||
|
private static final String ADDRESS_HEX_STRING;
|
||||||
|
|
||||||
|
static {
|
||||||
|
byte[] address;
|
||||||
|
try {
|
||||||
|
address = InetAddress.getLocalHost().getAddress();
|
||||||
|
}
|
||||||
|
catch ( Exception e ) {
|
||||||
|
address = new byte[4];
|
||||||
|
}
|
||||||
|
ADDRESS_BYTES = address;
|
||||||
|
ADDRESS_INT = BytesHelper.toInt( ADDRESS_BYTES );
|
||||||
|
ADDRESS_HEX_STRING = format( ADDRESS_INT );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getAddressBytes() {
|
||||||
|
return ADDRESS_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getAddressInt() {
|
||||||
|
return ADDRESS_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAddressHexString() {
|
||||||
|
return ADDRESS_HEX_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// JVM identifier ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
private static final byte[] JVM_IDENTIFIER_BYTES;
|
||||||
|
private static final int JVM_IDENTIFIER_INT;
|
||||||
|
private static final String JVM_IDENTIFIER_HEX_STRING;
|
||||||
|
|
||||||
|
static {
|
||||||
|
JVM_IDENTIFIER_INT = (int) ( System.currentTimeMillis() >>> 8 );
|
||||||
|
JVM_IDENTIFIER_BYTES = BytesHelper.fromInt( JVM_IDENTIFIER_INT );
|
||||||
|
JVM_IDENTIFIER_HEX_STRING = format( JVM_IDENTIFIER_INT );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getJvmIdentifierBytes() {
|
||||||
|
return JVM_IDENTIFIER_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getJvmIdentifierInt() {
|
||||||
|
return JVM_IDENTIFIER_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getJvmIdentifierHexString() {
|
||||||
|
return JVM_IDENTIFIER_HEX_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// counter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
private static short counter = (short) 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique in a millisecond for this JVM instance (unless there are > Short.MAX_VALUE instances created in a
|
||||||
|
* millisecond)
|
||||||
|
*/
|
||||||
|
public static short getCountShort() {
|
||||||
|
synchronized ( Helper.class ) {
|
||||||
|
if ( counter < 0 ) {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
return counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getCountBytes() {
|
||||||
|
return BytesHelper.fromShort( getCountShort() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
public static String format(int value) {
|
||||||
|
final String formatted = Integer.toHexString( value );
|
||||||
|
StringBuffer buf = new StringBuffer( "00000000".intern() );
|
||||||
|
buf.replace( 8 - formatted.length(), 8, formatted );
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(short value) {
|
||||||
|
String formatted = Integer.toHexString( value );
|
||||||
|
StringBuffer buf = new StringBuffer( "0000" );
|
||||||
|
buf.replace( 4 - formatted.length(), 4, formatted );
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws UnknownHostException {
|
||||||
|
byte[] addressBytes = InetAddress.getLocalHost().getAddress();
|
||||||
|
System.out.println( "Raw ip address bytes : " + addressBytes.toString() );
|
||||||
|
|
||||||
|
int addressInt = BytesHelper.toInt( addressBytes );
|
||||||
|
System.out.println( "ip address int : " + addressInt );
|
||||||
|
|
||||||
|
String formatted = Integer.toHexString( addressInt );
|
||||||
|
StringBuffer buf = new StringBuffer( "00000000" );
|
||||||
|
buf.replace( 8 - formatted.length(), 8, formatted );
|
||||||
|
String addressHex = buf.toString();
|
||||||
|
System.out.println( "ip address hex : " + addressHex );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.id.uuid;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.id.UUIDGenerationStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a "random" UUID generation strategy as defined by the {@link UUID#randomUUID()} method.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class StandardRandomStrategy implements UUIDGenerationStrategy {
|
||||||
|
public static final StandardRandomStrategy INSTANCE = new StandardRandomStrategy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variant 4 (random) strategy
|
||||||
|
*/
|
||||||
|
public int getGeneratedVersion() {
|
||||||
|
// a "random" strategy
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to {@link UUID#randomUUID()}
|
||||||
|
*/
|
||||||
|
public UUID generateUUID(SessionImplementor session) {
|
||||||
|
return UUID.randomUUID();
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,6 +73,8 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
register( CurrencyType.INSTANCE );
|
register( CurrencyType.INSTANCE );
|
||||||
register( TimeZoneType.INSTANCE );
|
register( TimeZoneType.INSTANCE );
|
||||||
register( ClassType.INSTANCE );
|
register( ClassType.INSTANCE );
|
||||||
|
register( UUIDBinaryType.INSTANCE );
|
||||||
|
register( UUIDCharType.INSTANCE );
|
||||||
|
|
||||||
register( BinaryType.INSTANCE );
|
register( BinaryType.INSTANCE );
|
||||||
register( WrapperBinaryType.INSTANCE );
|
register( WrapperBinaryType.INSTANCE );
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.sql.BinaryTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type mapping {@link java.sql.Types#BINARY} and {@link UUID}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UUIDBinaryType extends AbstractSingleColumnStandardBasicType<UUID> {
|
||||||
|
public static final UUIDBinaryType INSTANCE = new UUIDBinaryType();
|
||||||
|
|
||||||
|
public UUIDBinaryType() {
|
||||||
|
super( BinaryTypeDescriptor.INSTANCE, UUIDTypeDescriptor.INSTANCE );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "uuid-binary";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean registerUnderJavaType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.sql.CharTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type mapping {@link java.sql.Types#CHAR} (or {@link java.sql.Types#VARCHAR}) and {@link java.util.UUID}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UUIDCharType extends AbstractSingleColumnStandardBasicType<UUID> implements LiteralType<UUID> {
|
||||||
|
public static final UUIDCharType INSTANCE = new UUIDCharType();
|
||||||
|
|
||||||
|
public UUIDCharType() {
|
||||||
|
super( CharTypeDescriptor.INSTANCE, UUIDTypeDescriptor.INSTANCE );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "uuid-char";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String objectToSQLString(UUID value, Dialect dialect) throws Exception {
|
||||||
|
return StringType.INSTANCE.objectToSQLString( value.toString(), dialect );
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,7 +29,7 @@ import java.util.TimeZone;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO : javadoc
|
* Descriptor for {@link TimeZone} handling.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -79,6 +79,6 @@ public class TimeZoneTypeDescriptor extends AbstractTypeDescriptor<TimeZone> {
|
||||||
if ( String.class.isInstance( value ) ) {
|
if ( String.class.isInstance( value ) ) {
|
||||||
return fromString( (String) value );
|
return fromString( (String) value );
|
||||||
}
|
}
|
||||||
throw unknownUnwrap( value.getClass() );
|
throw unknownWrap( value.getClass() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.type.descriptor.java;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.util.BytesHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descriptor for {@link UUID} handling.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UUIDTypeDescriptor extends AbstractTypeDescriptor<UUID> {
|
||||||
|
public static final UUIDTypeDescriptor INSTANCE = new UUIDTypeDescriptor();
|
||||||
|
|
||||||
|
public UUIDTypeDescriptor() {
|
||||||
|
super( UUID.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(UUID value) {
|
||||||
|
return ToStringTransformer.INSTANCE.transform( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID fromString(String string) {
|
||||||
|
return ToStringTransformer.INSTANCE.parse( string );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
public <X> X unwrap(UUID value, Class<X> type, WrapperOptions options) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( UUID.class.isAssignableFrom( type ) ) {
|
||||||
|
return (X) PassThroughTransformer.INSTANCE.transform( value );
|
||||||
|
}
|
||||||
|
if ( String.class.isAssignableFrom( type ) ) {
|
||||||
|
return (X) ToStringTransformer.INSTANCE.transform( value );
|
||||||
|
}
|
||||||
|
if ( byte[].class.isAssignableFrom( type ) ) {
|
||||||
|
return (X) ToBytesTransformer.INSTANCE.transform( value );
|
||||||
|
}
|
||||||
|
throw unknownUnwrap( type );
|
||||||
|
}
|
||||||
|
|
||||||
|
public <X> UUID wrap(X value, WrapperOptions options) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( UUID.class.isInstance( value ) ) {
|
||||||
|
return PassThroughTransformer.INSTANCE.parse( value );
|
||||||
|
}
|
||||||
|
if ( String.class.isInstance( value ) ) {
|
||||||
|
return ToStringTransformer.INSTANCE.parse( value );
|
||||||
|
}
|
||||||
|
if ( byte[].class.isInstance( value ) ) {
|
||||||
|
return ToBytesTransformer.INSTANCE.parse( value );
|
||||||
|
}
|
||||||
|
throw unknownWrap( value.getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface ValueTransformer {
|
||||||
|
public Serializable transform(UUID uuid);
|
||||||
|
public UUID parse(Object value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PassThroughTransformer implements ValueTransformer {
|
||||||
|
public static final PassThroughTransformer INSTANCE = new PassThroughTransformer();
|
||||||
|
|
||||||
|
public UUID transform(UUID uuid) {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID parse(Object value) {
|
||||||
|
return (UUID)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ToStringTransformer implements ValueTransformer {
|
||||||
|
public static final ToStringTransformer INSTANCE = new ToStringTransformer();
|
||||||
|
|
||||||
|
public String transform(UUID uuid) {
|
||||||
|
return uuid.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID parse(Object value) {
|
||||||
|
return UUID.fromString( (String) value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ToBytesTransformer implements ValueTransformer {
|
||||||
|
public static final ToBytesTransformer INSTANCE = new ToBytesTransformer();
|
||||||
|
|
||||||
|
public byte[] transform(UUID uuid) {
|
||||||
|
byte[] bytes = new byte[16];
|
||||||
|
System.arraycopy( BytesHelper.fromLong( uuid.getMostSignificantBits() ), 0, bytes, 0, 8 );
|
||||||
|
System.arraycopy( BytesHelper.fromLong( uuid.getLeastSignificantBits() ), 0, bytes, 8, 8 );
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID parse(Object value) {
|
||||||
|
byte[] msb = new byte[8];
|
||||||
|
byte[] lsb = new byte[8];
|
||||||
|
System.arraycopy( value, 0, msb, 0, 8 );
|
||||||
|
System.arraycopy( value, 8, lsb, 0, 8 );
|
||||||
|
return new UUID( BytesHelper.asLong( msb ), BytesHelper.asLong( lsb ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.type.descriptor.java;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descriptor for {@link URL} handling.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UrlTypeDescriptor extends AbstractTypeDescriptor<URL> {
|
||||||
|
public static final UrlTypeDescriptor INSTANCE = new UrlTypeDescriptor();
|
||||||
|
|
||||||
|
public UrlTypeDescriptor() {
|
||||||
|
super( URL.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(URL value) {
|
||||||
|
return value.toExternalForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL fromString(String string) {
|
||||||
|
try {
|
||||||
|
return new URL( string );
|
||||||
|
}
|
||||||
|
catch ( MalformedURLException e ) {
|
||||||
|
throw new HibernateException( "Unable to convert string [" + string + "] to URL : " + e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
public <X> X unwrap(URL value, Class<X> type, WrapperOptions options) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( String.class.isAssignableFrom( type ) ) {
|
||||||
|
return (X) toString( value );
|
||||||
|
}
|
||||||
|
throw unknownUnwrap( type );
|
||||||
|
}
|
||||||
|
|
||||||
|
public <X> URL wrap(X value, WrapperOptions options) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( String.class.isInstance( value ) ) {
|
||||||
|
return fromString( (String) value );
|
||||||
|
}
|
||||||
|
throw unknownWrap( value.getClass() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
* indicated by the @author tags or express copyright attribution
|
* indicated by the @author tags or express copyright attribution
|
||||||
* statements applied by the authors. All third-party contributions are
|
* statements applied by the authors. All third-party contributions are
|
||||||
* distributed under license by Red Hat Middleware LLC.
|
* distributed under license by Red Hat Inc.
|
||||||
*
|
*
|
||||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
@ -20,26 +20,123 @@
|
||||||
* Free Software Foundation, Inc.
|
* Free Software Foundation, Inc.
|
||||||
* 51 Franklin Street, Fifth Floor
|
* 51 Franklin Street, Fifth Floor
|
||||||
* Boston, MA 02110-1301 USA
|
* Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
package org.hibernate.util;
|
package org.hibernate.util;
|
||||||
|
|
||||||
public final class BytesHelper {
|
public final class BytesHelper {
|
||||||
|
|
||||||
private BytesHelper() {}
|
private BytesHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static int toInt( byte[] bytes ) {
|
/**
|
||||||
|
* Custom algorithm used to generate an int from a series of bytes.
|
||||||
|
* <p/>
|
||||||
|
* NOTE : this is different than interpreting the incoming bytes as an int value!
|
||||||
|
*
|
||||||
|
* @param bytes The bytes to use in generating the int.
|
||||||
|
*
|
||||||
|
* @return The generated int.
|
||||||
|
*/
|
||||||
|
public static int toInt(byte[] bytes) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i=0; i<4; i++) {
|
for ( int i = 0; i < 4; i++ ) {
|
||||||
result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
|
result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpret a short as its binary form
|
||||||
|
*
|
||||||
|
* @param shortValue The short to interpret to binary
|
||||||
|
*
|
||||||
|
* @return The binary
|
||||||
|
*/
|
||||||
|
public static byte[] fromShort(int shortValue) {
|
||||||
|
byte[] bytes = new byte[2];
|
||||||
|
bytes[0] = (byte) ( shortValue >> 8 );
|
||||||
|
bytes[1] = (byte) ( ( shortValue << 8 ) >> 8 );
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpret an int as its binary form
|
||||||
|
*
|
||||||
|
* @param intValue The int to interpret to binary
|
||||||
|
*
|
||||||
|
* @return The binary
|
||||||
|
*/
|
||||||
|
public static byte[] fromInt(int intValue) {
|
||||||
|
byte[] bytes = new byte[4];
|
||||||
|
bytes[0] = (byte) ( intValue >> 24 );
|
||||||
|
bytes[1] = (byte) ( ( intValue << 8 ) >> 24 );
|
||||||
|
bytes[2] = (byte) ( ( intValue << 16 ) >> 24 );
|
||||||
|
bytes[3] = (byte) ( ( intValue << 24 ) >> 24 );
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpret a long as its binary form
|
||||||
|
*
|
||||||
|
* @param longValue The long to interpret to binary
|
||||||
|
*
|
||||||
|
* @return The binary
|
||||||
|
*/
|
||||||
|
public static byte[] fromLong(long longValue) {
|
||||||
|
byte[] bytes = new byte[8];
|
||||||
|
bytes[0] = (byte) ( longValue >> 56 );
|
||||||
|
bytes[1] = (byte) ( ( longValue << 8 ) >> 56 );
|
||||||
|
bytes[2] = (byte) ( ( longValue << 16 ) >> 56 );
|
||||||
|
bytes[3] = (byte) ( ( longValue << 24 ) >> 56 );
|
||||||
|
bytes[4] = (byte) ( ( longValue << 32 ) >> 56 );
|
||||||
|
bytes[5] = (byte) ( ( longValue << 40 ) >> 56 );
|
||||||
|
bytes[6] = (byte) ( ( longValue << 48 ) >> 56 );
|
||||||
|
bytes[7] = (byte) ( ( longValue << 56 ) >> 56 );
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpret the binary representation of a long.
|
||||||
|
*
|
||||||
|
* @param bytes The bytes to interpret.
|
||||||
|
*
|
||||||
|
* @return The long
|
||||||
|
*/
|
||||||
|
public static long asLong(byte[] bytes) {
|
||||||
|
if ( bytes == null ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( bytes.length != 8 ) {
|
||||||
|
throw new IllegalArgumentException( "Expecting 8 byte values to construct a long" );
|
||||||
|
}
|
||||||
|
long value = 0;
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
value = (value << 8) | (bytes[i] & 0xff);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toBinaryString(byte value) {
|
||||||
|
String formatted = Integer.toBinaryString( value );
|
||||||
|
if ( formatted.length() > 8 ) {
|
||||||
|
formatted = formatted.substring( formatted.length() - 8 );
|
||||||
|
}
|
||||||
|
StringBuffer buf = new StringBuffer( "00000000" );
|
||||||
|
buf.replace( 8 - formatted.length(), 8, formatted );
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toBinaryString(int value) {
|
||||||
|
String formatted = Long.toBinaryString( value );
|
||||||
|
StringBuffer buf = new StringBuffer( StringHelper.repeat( '0', 32 ) );
|
||||||
|
buf.replace( 64 - formatted.length(), 64, formatted );
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toBinaryString(long value) {
|
||||||
|
String formatted = Long.toBinaryString( value );
|
||||||
|
StringBuffer buf = new StringBuffer( StringHelper.repeat( '0', 64 ) );
|
||||||
|
buf.replace( 64 - formatted.length(), 64, formatted );
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.id.uuid;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class CustomVersionOneStrategyTest extends TestCase {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println( System.currentTimeMillis() );
|
||||||
|
System.out.println( Long.MAX_VALUE );
|
||||||
|
}
|
||||||
|
public void testUniqueCounter() {
|
||||||
|
CustomVersionOneStrategy strategy = new CustomVersionOneStrategy();
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
UUID uuid1 = new UUID(
|
||||||
|
strategy.getMostSignificantBits(),
|
||||||
|
CustomVersionOneStrategy.generateLeastSignificantBits( now )
|
||||||
|
);
|
||||||
|
assertEquals( 2, uuid1.variant() );
|
||||||
|
assertEquals( 1, uuid1.version() );
|
||||||
|
|
||||||
|
for ( int i = 0; i < 100; i++ ) {
|
||||||
|
UUID uuidX = new UUID(
|
||||||
|
strategy.getMostSignificantBits(),
|
||||||
|
CustomVersionOneStrategy.generateLeastSignificantBits( now )
|
||||||
|
);
|
||||||
|
assertEquals( 2, uuidX.variant() );
|
||||||
|
assertEquals( 1, uuidX.version() );
|
||||||
|
assertFalse( uuid1.equals( uuidX ) );
|
||||||
|
assertEquals( uuid1.getMostSignificantBits(), uuidX.getMostSignificantBits() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRangeOfValues() {
|
||||||
|
CustomVersionOneStrategy strategy = new CustomVersionOneStrategy();
|
||||||
|
|
||||||
|
UUID uuid = new UUID(
|
||||||
|
strategy.getMostSignificantBits(),
|
||||||
|
CustomVersionOneStrategy.generateLeastSignificantBits( 0 )
|
||||||
|
);
|
||||||
|
assertEquals( 2, uuid.variant() );
|
||||||
|
assertEquals( 1, uuid.version() );
|
||||||
|
|
||||||
|
uuid = new UUID(
|
||||||
|
strategy.getMostSignificantBits(),
|
||||||
|
CustomVersionOneStrategy.generateLeastSignificantBits( Long.MAX_VALUE )
|
||||||
|
);
|
||||||
|
assertEquals( 2, uuid.variant() );
|
||||||
|
assertEquals( 1, uuid.version() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.UrlTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class BasicTypeRegistryTest extends TestCase {
|
||||||
|
private final BasicTypeRegistry registry = new BasicTypeRegistry();
|
||||||
|
|
||||||
|
public void testOverriding() {
|
||||||
|
BasicType type = registry.getRegisteredType( "uuid-binary" );
|
||||||
|
assertSame( UUIDBinaryType.INSTANCE, type );
|
||||||
|
type = registry.getRegisteredType( UUID.class.getName() );
|
||||||
|
assertSame( UUIDBinaryType.INSTANCE, type );
|
||||||
|
|
||||||
|
BasicType override = new UUIDCharType() {
|
||||||
|
@Override
|
||||||
|
protected boolean registerUnderJavaType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
registry.register( override );
|
||||||
|
type = registry.getRegisteredType( UUID.class.getName() );
|
||||||
|
assertNotSame( UUIDBinaryType.INSTANCE, type );
|
||||||
|
assertSame( override, type );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExpanding() {
|
||||||
|
BasicType type = registry.getRegisteredType( URL.class.getName() );
|
||||||
|
assertNull( type );
|
||||||
|
|
||||||
|
registry.register( UrlType.INSTANCE );
|
||||||
|
type = registry.getRegisteredType( URL.class.getName() );
|
||||||
|
assertNotNull( type );
|
||||||
|
assertSame( UrlType.INSTANCE, type );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UrlType extends AbstractSingleColumnStandardBasicType<URL> {
|
||||||
|
public static final UrlType INSTANCE = new UrlType();
|
||||||
|
|
||||||
|
public UrlType() {
|
||||||
|
super( VarcharTypeDescriptor.INSTANCE, UrlTypeDescriptor.INSTANCE );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "url";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean registerUnderJavaType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -583,8 +583,37 @@
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</section>
|
</section>
|
||||||
|
<section id="types.basic.value.uuid">
|
||||||
|
<title><classname>java.util.UUID</classname></title>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><classname>org.hibernate.type.UUIDBinaryType</classname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Maps a java.util.UUID to a JDBC BINARY
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Registered under <literal>uuid-binary</literal> and <literal>java.util.UUID</literal>
|
||||||
|
in the type registry (see <xref linkend="types.registry"/>).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><classname>org.hibernate.type.UUIDCharType</classname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Maps a java.util.UUID to a JDBC CHAR (though VARCHAR is fine too for existing schemas)
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Registered under <literal>uuid-char</literal> in the type registry (see
|
||||||
|
<xref linkend="types.registry"/>).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</section>
|
||||||
<section id="types.basic.value.serializable">
|
<section id="types.basic.value.serializable">
|
||||||
<title>java.io.Serializable</title>
|
<title><classname>java.io.Serializable</classname></title>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><classname>org.hibernate.type.SerializableType</classname></term>
|
<term><classname>org.hibernate.type.SerializableType</classname></term>
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
~ indicated by the @author tags or express copyright attribution
|
||||||
|
~ statements applied by the authors. All third-party contributions are
|
||||||
|
~ distributed under license by Red Hat Inc.
|
||||||
|
~
|
||||||
|
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
~
|
||||||
|
~ This program is distributed in the hope that it will be useful,
|
||||||
|
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
~ for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU Lesser General Public License
|
||||||
|
~ along with this distribution; if not, write to:
|
||||||
|
~ Free Software Foundation, Inc.
|
||||||
|
~ 51 Franklin Street, Fifth Floor
|
||||||
|
~ Boston, MA 02110-1301 USA
|
||||||
|
-->
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping package="org.hibernate.test.id.uuid.sqlrep">
|
||||||
|
|
||||||
|
<class name="Node">
|
||||||
|
|
||||||
|
<id name="id">
|
||||||
|
<generator class="uuid2"/>
|
||||||
|
</id>
|
||||||
|
<property name="name"/>
|
||||||
|
<many-to-one name="parent"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.id.uuid.sqlrep;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class Node {
|
||||||
|
private UUID id;
|
||||||
|
private String name;
|
||||||
|
private Node parent;
|
||||||
|
|
||||||
|
public Node() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(String name, Node parent) {
|
||||||
|
this.name = name;
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(Node parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.id.uuid.sqlrep.sqlbinary;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||||
|
import org.hibernate.test.id.uuid.sqlrep.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UUIDBinaryTest extends FunctionalTestCase {
|
||||||
|
public UUIDBinaryTest(String string) {
|
||||||
|
super( string );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getMappings() {
|
||||||
|
return new String[] { "id/uuid/sqlrep/Node.hbm.xml" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUsage() {
|
||||||
|
Session session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Node root = new Node( "root" );
|
||||||
|
session.save( root );
|
||||||
|
assertNotNull( root.getId() );
|
||||||
|
Node child = new Node( "child", root );
|
||||||
|
session.save( child );
|
||||||
|
assertNotNull( child.getId() );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Node node = (Node) session.get( Node.class, root.getId() );
|
||||||
|
assertNotNull( node );
|
||||||
|
node = (Node) session.get( Node.class, child.getId() );
|
||||||
|
assertNotNull( node );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
// test joining
|
||||||
|
node = (Node) session.createQuery( "from Node n join fetch n.parent where n.parent is not null" ).uniqueResult();
|
||||||
|
assertNotNull( node );
|
||||||
|
assertNotNull( node.getParent() );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.delete( child );
|
||||||
|
session.delete( root );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.id.uuid.sqlrep.sqlchar;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.test.id.uuid.sqlrep.sqlbinary.UUIDBinaryTest;
|
||||||
|
import org.hibernate.type.UUIDCharType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class UUIDCharTest extends UUIDBinaryTest {
|
||||||
|
public UUIDCharTest(String string) {
|
||||||
|
super( string );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Configuration cfg) {
|
||||||
|
cfg.registerTypeOverride(
|
||||||
|
new UUIDCharType() {
|
||||||
|
@Override
|
||||||
|
protected boolean registerUnderJavaType() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.id.uuid.strategy;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class CustomStrategyTest extends FunctionalTestCase {
|
||||||
|
public CustomStrategyTest(String string) {
|
||||||
|
super( string );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getMappings() {
|
||||||
|
return new String[] { "id/uuid/strategy/Node.hbm.xml" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUsage() {
|
||||||
|
Session session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Node node = new Node();
|
||||||
|
session.save( node );
|
||||||
|
assertNotNull( node.getId() );
|
||||||
|
assertEquals( 2, node.getId().variant() );
|
||||||
|
assertEquals( 1, node.getId().version() );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.delete( node );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
~ indicated by the @author tags or express copyright attribution
|
||||||
|
~ statements applied by the authors. All third-party contributions are
|
||||||
|
~ distributed under license by Red Hat Inc.
|
||||||
|
~
|
||||||
|
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
~
|
||||||
|
~ This program is distributed in the hope that it will be useful,
|
||||||
|
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
~ for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU Lesser General Public License
|
||||||
|
~ along with this distribution; if not, write to:
|
||||||
|
~ Free Software Foundation, Inc.
|
||||||
|
~ 51 Franklin Street, Fifth Floor
|
||||||
|
~ Boston, MA 02110-1301 USA
|
||||||
|
-->
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping package="org.hibernate.test.id.uuid.strategy">
|
||||||
|
|
||||||
|
<class name="Node">
|
||||||
|
|
||||||
|
<id name="id">
|
||||||
|
<generator class="uuid2">
|
||||||
|
<!-- the "standard random" strategy gets tested in the other id.uuid tests -->
|
||||||
|
<param name="uuid_gen_strategy_class">org.hibernate.id.uuid.CustomVersionOneStrategy</param>
|
||||||
|
</generator>
|
||||||
|
</id>
|
||||||
|
<property name="name"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.id.uuid.strategy;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class Node {
|
||||||
|
private UUID id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Node() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue