mirror of https://github.com/apache/openjpa.git
OPENJPA-545 committing patch provided by Jeremy Bauer
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@671319 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
37cb4af35d
commit
fb78813259
|
@ -3545,6 +3545,10 @@ public class BrokerImpl
|
|||
return UUIDHexSeq.getInstance();
|
||||
case ValueStrategies.UUID_STRING:
|
||||
return UUIDStringSeq.getInstance();
|
||||
case ValueStrategies.UUID_TYPE4_HEX:
|
||||
return UUIDType4HexSeq.getInstance();
|
||||
case ValueStrategies.UUID_TYPE4_STRING:
|
||||
return UUIDType4StringSeq.getInstance();
|
||||
case ValueStrategies.SEQUENCE:
|
||||
SequenceMetaData smd = (fmd == null)
|
||||
? meta.getIdentitySequenceMetaData()
|
||||
|
|
|
@ -50,7 +50,7 @@ public class UUIDHexSeq
|
|||
}
|
||||
|
||||
public synchronized Object next(StoreContext ctx, ClassMetaData meta) {
|
||||
_last = UUIDGenerator.nextHex();
|
||||
_last = UUIDGenerator.nextHex(UUIDGenerator.TYPE1);
|
||||
return _last;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ public class UUIDStringSeq
|
|||
}
|
||||
|
||||
public synchronized Object next(StoreContext ctx, ClassMetaData meta) {
|
||||
_last = UUIDGenerator.nextString();
|
||||
_last = UUIDGenerator.nextString(UUIDGenerator.TYPE1);
|
||||
return _last;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.kernel;
|
||||
|
||||
import org.apache.openjpa.lib.util.UUIDGenerator;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
|
||||
/**
|
||||
* Sequence for generating 32-character hex Type 4 UUID strings.
|
||||
*
|
||||
* @author Jeremy Bauer
|
||||
*/
|
||||
public class UUIDType4HexSeq
|
||||
implements Seq {
|
||||
|
||||
private static final UUIDType4HexSeq _instance = new UUIDType4HexSeq();
|
||||
|
||||
private String _last = null;
|
||||
|
||||
/**
|
||||
* Return the singleton instance.
|
||||
*/
|
||||
public static UUIDType4HexSeq getInstance() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide constructor.
|
||||
*/
|
||||
private UUIDType4HexSeq() {
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
}
|
||||
|
||||
public synchronized Object next(StoreContext ctx, ClassMetaData meta) {
|
||||
_last = UUIDGenerator.nextHex(UUIDGenerator.TYPE4);
|
||||
return _last;
|
||||
}
|
||||
|
||||
public synchronized Object current(StoreContext ctx, ClassMetaData meta) {
|
||||
return _last;
|
||||
}
|
||||
|
||||
public void allocate(int additional, StoreContext ctx, ClassMetaData meta) {
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.openjpa.kernel;
|
||||
|
||||
import org.apache.openjpa.lib.util.UUIDGenerator;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
|
||||
/**
|
||||
* Sequence for generating 16-character UUID strings.
|
||||
*
|
||||
* @author Jeremy Bauer
|
||||
*/
|
||||
public class UUIDType4StringSeq
|
||||
implements Seq {
|
||||
|
||||
private static final UUIDType4StringSeq _instance = new UUIDType4StringSeq();
|
||||
|
||||
private String _last = null;
|
||||
|
||||
/**
|
||||
* Return the singleton instance.
|
||||
*/
|
||||
public static UUIDType4StringSeq getInstance() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide constructor.
|
||||
*/
|
||||
private UUIDType4StringSeq() {
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
}
|
||||
|
||||
public synchronized Object next(StoreContext ctx, ClassMetaData meta) {
|
||||
_last = UUIDGenerator.nextString(UUIDGenerator.TYPE4);
|
||||
return _last;
|
||||
}
|
||||
|
||||
public synchronized Object current(StoreContext ctx, ClassMetaData meta) {
|
||||
return _last;
|
||||
}
|
||||
|
||||
public void allocate(int additional, StoreContext ctx, ClassMetaData meta) {
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
}
|
|
@ -68,6 +68,16 @@ public class ValueStrategies {
|
|||
*/
|
||||
public static final int UUID_HEX = 6;
|
||||
|
||||
/**
|
||||
* "uuid-type4-string" value strategy.
|
||||
*/
|
||||
public static final int UUID_TYPE4_STRING = 7;
|
||||
|
||||
/**
|
||||
* "uuid-type4-hex" value strategy.
|
||||
*/
|
||||
public static final int UUID_TYPE4_HEX = 8;
|
||||
|
||||
private static final Localizer _loc = Localizer.forPackage
|
||||
(ValueStrategies.class);
|
||||
|
||||
|
@ -82,6 +92,8 @@ public class ValueStrategies {
|
|||
_map.put("increment", Numbers.valueOf(INCREMENT));
|
||||
_map.put("uuid-string", Numbers.valueOf(UUID_STRING));
|
||||
_map.put("uuid-hex", Numbers.valueOf(UUID_HEX));
|
||||
_map.put("uuid-type4-string", Numbers.valueOf(UUID_TYPE4_STRING));
|
||||
_map.put("uuid-type4-hex", Numbers.valueOf(UUID_TYPE4_HEX));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -160,9 +160,13 @@ public class ImplHelper {
|
|||
return JavaTypes.convert(smd.getInstance(ctx.getClassLoader()).
|
||||
next(ctx, meta), typeCode);
|
||||
case ValueStrategies.UUID_STRING:
|
||||
return UUIDGenerator.nextString();
|
||||
return UUIDGenerator.nextString(UUIDGenerator.TYPE1);
|
||||
case ValueStrategies.UUID_HEX:
|
||||
return UUIDGenerator.nextHex();
|
||||
return UUIDGenerator.nextHex(UUIDGenerator.TYPE1);
|
||||
case ValueStrategies.UUID_TYPE4_STRING:
|
||||
return UUIDGenerator.nextString(UUIDGenerator.TYPE4);
|
||||
case ValueStrategies.UUID_TYPE4_HEX:
|
||||
return UUIDGenerator.nextHex(UUIDGenerator.TYPE4);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -22,16 +22,18 @@ import java.io.IOException;
|
|||
import java.net.InetAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang.exception.NestableRuntimeException;
|
||||
|
||||
/**
|
||||
* UUID value generator. Based on the time-based generator in the Apache
|
||||
* Commons Id project: http://jakarta.apache.org/commons/sandbox/id/uuid.html
|
||||
* UUID value generator. Type 1 generator is based on the time-based generator
|
||||
* in the Apache Commons Id project: http://jakarta.apache.org/commons/sandbox
|
||||
* /id/uuid.html The type 4 generator uses the standard Java UUID generator.
|
||||
*
|
||||
* The code has been vastly simplified and modified to replace the ethernet
|
||||
* address of the host machine with the IP, since we do not want to require
|
||||
* native libs and Java cannot access the MAC address directly.
|
||||
* The type 1 code has been vastly simplified and modified to replace the
|
||||
* ethernet address of the host machine with the IP, since we do not want to
|
||||
* require native libs and Java cannot access the MAC address directly.
|
||||
*
|
||||
* In spirit, implements the IETF UUID draft specification, found here:<br />
|
||||
* http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/draft-leach-uuids-guids-01
|
||||
|
@ -43,6 +45,10 @@ import org.apache.commons.lang.exception.NestableRuntimeException;
|
|||
*/
|
||||
public class UUIDGenerator {
|
||||
|
||||
// supported UUID types
|
||||
public static final int TYPE1 = 1;
|
||||
public static final int TYPE4 = 4;
|
||||
|
||||
// indexes within the uuid array for certain boundaries
|
||||
private static final byte IDX_TIME_HI = 6;
|
||||
private static final byte IDX_TYPE = 6; // multiplexed
|
||||
|
@ -68,13 +74,12 @@ public class UUIDGenerator {
|
|||
private final static byte TYPE_TIME_BASED = 0x10;
|
||||
|
||||
// random number generator used to reduce conflicts with other JVMs, and
|
||||
// hasher for strings. note that secure random is very slow the first time
|
||||
// it is used; consider switching to a standard random
|
||||
private static final Random RANDOM = new SecureRandom();
|
||||
// hasher for strings.
|
||||
private static Random RANDOM;
|
||||
|
||||
// 4-byte IP address + 2 random bytes to compensate for the fact that
|
||||
// the MAC address is usually 6 bytes
|
||||
private static final byte[] IP;
|
||||
private static byte[] IP;
|
||||
|
||||
// counter is initialized to 0 and is incremented for each uuid request
|
||||
// within the same timestamp window.
|
||||
|
@ -88,12 +93,21 @@ public class UUIDGenerator {
|
|||
// when it overflows
|
||||
private static long _lastMillis = 0L;
|
||||
private static final int MAX_14BIT = 0x3FFF;
|
||||
private static short _seq = (short) RANDOM.nextInt(MAX_14BIT);
|
||||
|
||||
private static short _seq = 0;
|
||||
|
||||
/*
|
||||
* Static initializer to get the IP address of the host machine.
|
||||
* Initializer for type 1 UUIDs. Creates random generator and genenerates
|
||||
* the node portion of the UUID using the IP address.
|
||||
*/
|
||||
static {
|
||||
private static synchronized void initializeForType1()
|
||||
{
|
||||
if (RANDOM != null)
|
||||
return;
|
||||
// note that secure random is very slow the first time
|
||||
// it is used; consider switching to a standard random
|
||||
RANDOM = new SecureRandom();
|
||||
_seq = (short) RANDOM.nextInt(MAX_14BIT);
|
||||
|
||||
byte[] ip = null;
|
||||
try {
|
||||
ip = InetAddress.getLocalHost().getAddress();
|
||||
|
@ -103,13 +117,25 @@ public class UUIDGenerator {
|
|||
|
||||
IP = new byte[6];
|
||||
RANDOM.nextBytes(IP);
|
||||
System.arraycopy(ip, 0, IP, 2, ip.length);
|
||||
System.arraycopy(ip, 0, IP, 2, ip.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a unique UUID value.
|
||||
*/
|
||||
public static byte[] next() {
|
||||
public static byte[] next(int type) {
|
||||
if (type == TYPE4) {
|
||||
return createType4();
|
||||
}
|
||||
return createType1();
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a type 1 UUID
|
||||
*/
|
||||
public static byte[] createType1() {
|
||||
if (RANDOM == null)
|
||||
initializeForType1();
|
||||
// set ip addr
|
||||
byte[] uuid = new byte[16];
|
||||
System.arraycopy(IP, 0, uuid, 10, IP.length);
|
||||
|
@ -147,11 +173,32 @@ public class UUIDGenerator {
|
|||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a type 4 UUID
|
||||
*/
|
||||
private static byte[] createType4() {
|
||||
UUID type4 = UUID.randomUUID();
|
||||
byte[] uuid = new byte[16];
|
||||
longToBytes(type4.getMostSignificantBits(), uuid, 0);
|
||||
longToBytes(type4.getLeastSignificantBits(), uuid, 8);
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts a long to byte values, setting them in a byte array
|
||||
* at a given starting position.
|
||||
*/
|
||||
private static void longToBytes(long longVal, byte[] buf, int sPos) {
|
||||
sPos += 7;
|
||||
for(int i = 0; i < 8; i++)
|
||||
buf[sPos-i] = (byte)(longVal >>> (i * 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next unique uuid value as a 16-character string.
|
||||
*/
|
||||
public static String nextString() {
|
||||
byte[] bytes = next();
|
||||
public static String nextString(int type) {
|
||||
byte[] bytes = next(type);
|
||||
try {
|
||||
return new String(bytes, "ISO-8859-1");
|
||||
} catch (Exception e) {
|
||||
|
@ -162,8 +209,8 @@ public class UUIDGenerator {
|
|||
/**
|
||||
* Return the next unique uuid value as a 32-character hex string.
|
||||
*/
|
||||
public static String nextHex() {
|
||||
return Base16Encoder.encode(next());
|
||||
public static String nextHex(int type) {
|
||||
return Base16Encoder.encode(next(type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,6 +221,8 @@ public class UUIDGenerator {
|
|||
*/
|
||||
// package-visibility for testing
|
||||
static long getTime() {
|
||||
if (RANDOM == null)
|
||||
initializeForType1();
|
||||
long newTime = getUUIDTime();
|
||||
if (newTime <= _lastMillis) {
|
||||
incrementSequence();
|
||||
|
|
|
@ -33,13 +33,39 @@ public class TestUUIDGenerator extends TestCase {
|
|||
public void testUniqueString() {
|
||||
Set seen = new HashSet();
|
||||
for (int i = 0; i < 10000; i++)
|
||||
assertTrue(seen.add(UUIDGenerator.nextString()));
|
||||
assertTrue(seen.add(
|
||||
UUIDGenerator.nextString(UUIDGenerator.TYPE1)));
|
||||
}
|
||||
|
||||
public void testUniqueHex() {
|
||||
Set seen = new HashSet();
|
||||
for (int i = 0; i < 10000; i++)
|
||||
assertTrue(seen.add(UUIDGenerator.nextHex()));
|
||||
assertTrue(seen.add(
|
||||
UUIDGenerator.nextHex(UUIDGenerator.TYPE1)));
|
||||
}
|
||||
|
||||
public void testUniqueType4String() {
|
||||
Set seen = new HashSet();
|
||||
for (int i = 0; i < 10000; i++)
|
||||
assertTrue(seen.add(
|
||||
UUIDGenerator.nextString(UUIDGenerator.TYPE4)));
|
||||
}
|
||||
|
||||
public void testUniqueType4Hex() {
|
||||
Set seen = new HashSet();
|
||||
for (int i = 0; i < 10000; i++)
|
||||
assertTrue(seen.add(
|
||||
UUIDGenerator.nextHex(UUIDGenerator.TYPE4)));
|
||||
}
|
||||
|
||||
public void testUniqueMixedTypesHex() {
|
||||
Set seen = new HashSet();
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
int type = (i % 2 == 0) ?
|
||||
UUIDGenerator.TYPE4 : UUIDGenerator.TYPE1;
|
||||
assertTrue(seen.add(
|
||||
UUIDGenerator.nextHex(type)));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetTime() {
|
||||
|
|
|
@ -43,14 +43,31 @@ public class GeneratedValues {
|
|||
sequenceName="org.apache.openjpa.persistence.generationtype.CustomSeq()")
|
||||
private int customSeqWithIndirectionField;
|
||||
|
||||
@GeneratedValue(generator="uuid-hex")
|
||||
private String uuidhex;
|
||||
|
||||
@GeneratedValue(generator="uuid-string")
|
||||
private String uuidstring;
|
||||
|
||||
@GeneratedValue(generator="uuid-type4-hex")
|
||||
private String uuidT4hex;
|
||||
|
||||
@GeneratedValue(generator="uuid-type4-string")
|
||||
private String uuidT4string;
|
||||
|
||||
public GeneratedValues() {
|
||||
super();
|
||||
}
|
||||
|
||||
public GeneratedValues(int id, long field) {
|
||||
public GeneratedValues(int id, long field, String uh, String us,
|
||||
String ut4h, String ut4s) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.field = field;
|
||||
this.uuidhex = uh;
|
||||
this.uuidstring = us;
|
||||
this.uuidT4hex = ut4h;
|
||||
this.uuidT4string = ut4s;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
|
@ -76,4 +93,36 @@ public class GeneratedValues {
|
|||
public int getCustomSeqWithIndirectionField() {
|
||||
return customSeqWithIndirectionField;
|
||||
}
|
||||
|
||||
public void setUuidhex(String uuidhex) {
|
||||
this.uuidhex = uuidhex;
|
||||
}
|
||||
|
||||
public String getUuidhex() {
|
||||
return uuidhex;
|
||||
}
|
||||
|
||||
public void setUuidstring(String uuidstring) {
|
||||
this.uuidstring = uuidstring;
|
||||
}
|
||||
|
||||
public String getUuidstring() {
|
||||
return uuidstring;
|
||||
}
|
||||
|
||||
public void setUuidT4hex(String uuidT4hex) {
|
||||
this.uuidT4hex = uuidT4hex;
|
||||
}
|
||||
|
||||
public String getUuidT4hex() {
|
||||
return uuidT4hex;
|
||||
}
|
||||
|
||||
public void setUuidT4string(String uuidT4string) {
|
||||
this.uuidT4string = uuidT4string;
|
||||
}
|
||||
|
||||
public String getUuidT4string() {
|
||||
return uuidT4string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,12 +46,16 @@ public class TestGeneratedValues extends SingleEMFTestCase {
|
|||
|
||||
assertFalse(gv.getId() == gv2.getId());
|
||||
assertFalse(gv.getField() == gv2.getField());
|
||||
assertFalse(gv.getUuidstring().equals(gv2.getUuidstring()));
|
||||
assertFalse(gv.getUuidhex().equals(gv2.getUuidhex()));
|
||||
assertFalse(gv.getUuidT4hex().equals(gv2.getUuidT4hex()));
|
||||
assertFalse(gv.getUuidT4string().equals(gv2.getUuidT4string()));
|
||||
}
|
||||
|
||||
public void testInitialValues() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
GeneratedValues gv = new GeneratedValues(7, 9);
|
||||
GeneratedValues gv = new GeneratedValues(7, 9, "a", "b", "c", "d");
|
||||
|
||||
try {
|
||||
em.getTransaction().begin();
|
||||
|
@ -133,4 +137,82 @@ public class TestGeneratedValues extends SingleEMFTestCase {
|
|||
|
||||
assertNotEquals(0, gv.getCustomSeqWithIndirectionField());
|
||||
}
|
||||
|
||||
public void testUUIDGenerators() {
|
||||
EntityManager em = emf.createEntityManager();
|
||||
|
||||
GeneratedValues gv = new GeneratedValues();
|
||||
em.getTransaction().begin();
|
||||
em.persist(gv);
|
||||
em.getTransaction().commit();
|
||||
|
||||
int id = gv.getId();
|
||||
|
||||
assertTrue(isStringUUID(gv.getUuidT4string(), 4));
|
||||
assertTrue(isStringUUID(gv.getUuidstring(), 1));
|
||||
assertTrue(isHexUUID(gv.getUuidhex(), 1));
|
||||
assertTrue(isHexUUID(gv.getUuidT4hex(), 4));
|
||||
|
||||
em.clear();
|
||||
|
||||
GeneratedValues gv2 = em.find(GeneratedValues.class, id);
|
||||
assertNotNull(gv2);
|
||||
// The string value could contain null values and such so length
|
||||
// calculations may be non-deterministic. For string generators,
|
||||
// simply ensure the fields are populated (not null).
|
||||
assertNotNull(gv2.getUuidstring());
|
||||
assertTrue(isHexUUID(gv2.getUuidhex(), 1));
|
||||
assertNotNull(gv2.getUuidT4string());
|
||||
assertTrue(isHexUUID(gv2.getUuidT4hex(), 4));
|
||||
|
||||
// Compare original hex values with new values. They should be equal.
|
||||
// Note: UUID 'string' values are not compared. In most cases they will
|
||||
// be the same, but in an environment where data is converted to
|
||||
// a considerably different character encoding of the database (ex.
|
||||
// Unicode -> EBCDIC) upon persistence, the uuid string returned by the
|
||||
// database may not be equal to the original value. This is a common
|
||||
// issue with string data, but even more likely for a uuids given that
|
||||
// uuid strings are produced from pseudo-random byte arrays, which yield
|
||||
// all sorts of variant characters.
|
||||
assertTrue(gv.getId() == gv2.getId());
|
||||
assertTrue(gv.getField() == gv2.getField());
|
||||
assertTrue(gv.getUuidhex().equals(gv2.getUuidhex()));
|
||||
assertTrue(gv.getUuidT4hex().equals(gv2.getUuidT4hex()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a uuid string is 16 characters long and is the expected type.
|
||||
*/
|
||||
private boolean isStringUUID(String value, int type) {
|
||||
if (value.length() != 16)
|
||||
return false;
|
||||
byte version = (byte)(value.charAt(6) >>> 4);
|
||||
if (type != version) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a uuid hex string value is 32 characters long, consists entirely
|
||||
* of hex digits and is the correct version.
|
||||
*/
|
||||
private boolean isHexUUID(String value, int type) {
|
||||
if (value.length() != 32)
|
||||
return false;
|
||||
char[] chArr = value.toCharArray();
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
char ch = chArr[i];
|
||||
if (!(Character.isDigit(ch) ||
|
||||
(ch >= 'a' && ch <= 'f') ||
|
||||
(ch >= 'A' && ch <= 'F')))
|
||||
return false;
|
||||
if (i == 12) {
|
||||
if (type == 1 && ch != '1')
|
||||
return false;
|
||||
if (type == 4 && ch != '4')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,18 @@ public class ExtensionsEntity {
|
|||
@GeneratedValue(generator = "uuid-hex")
|
||||
@Column(name = "UUID_HEX")
|
||||
private String uuid;
|
||||
|
||||
@GeneratedValue(generator = "uuid-string")
|
||||
@Column(name = "UUID_STRING")
|
||||
private String uuidString;
|
||||
|
||||
@GeneratedValue(generator = "uuid-type4-hex")
|
||||
@Column(name = "UUIDT4_HEX")
|
||||
private String uuidT4Hex;
|
||||
|
||||
@GeneratedValue(generator = "uuid-type4-string")
|
||||
@Column(name = "UUIDT4_STRING")
|
||||
private String uuidT4String;
|
||||
|
||||
@Basic(fetch = FetchType.LAZY)
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "system")
|
||||
|
|
|
@ -72,6 +72,12 @@ public class TestExtensionAnnotations
|
|||
public void testValueStrategy() {
|
||||
assertEquals(ValueStrategies.UUID_HEX,
|
||||
_mapping.getField("uuid").getValueStrategy());
|
||||
assertEquals(ValueStrategies.UUID_STRING,
|
||||
_mapping.getField("uuidString").getValueStrategy());
|
||||
assertEquals(ValueStrategies.UUID_TYPE4_HEX,
|
||||
_mapping.getField("uuidT4Hex").getValueStrategy());
|
||||
assertEquals(ValueStrategies.UUID_TYPE4_STRING,
|
||||
_mapping.getField("uuidT4String").getValueStrategy());
|
||||
FieldMapping seq = _mapping.getFieldMapping("seq");
|
||||
assertEquals(ValueStrategies.SEQUENCE, seq.getValueStrategy());
|
||||
assertEquals("system", seq.getValueSequenceName());
|
||||
|
|
|
@ -1220,6 +1220,10 @@ public class AnnotationPersistenceMetaDataParser
|
|||
return ValueStrategies.UUID_HEX;
|
||||
if (Generator.UUID_STRING.equals(generator))
|
||||
return ValueStrategies.UUID_STRING;
|
||||
if (Generator.UUID_TYPE4_HEX.equals(generator))
|
||||
return ValueStrategies.UUID_TYPE4_HEX;
|
||||
if (Generator.UUID_TYPE4_STRING.equals(generator))
|
||||
return ValueStrategies.UUID_TYPE4_STRING;
|
||||
throw new MetaDataException(_loc.get("generator-bad-strategy",
|
||||
context, generator));
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ public interface Generator {
|
|||
|
||||
public static final String UUID_HEX = "uuid-hex";
|
||||
public static final String UUID_STRING = "uuid-string";
|
||||
public static final String UUID_TYPE4_STRING = "uuid-type4-string";
|
||||
public static final String UUID_TYPE4_HEX = "uuid-type4-hex";
|
||||
|
||||
/**
|
||||
* The sequence name.
|
||||
|
|
|
@ -830,7 +830,7 @@ on any field, not just identity fields. Before using the <literal>IDENTITY
|
|||
<xref linkend="ref_guide_pc_oid_pkgen_autoinc"/> in the Reference Guide.
|
||||
</para>
|
||||
<para>
|
||||
OpenJPA also offers two additional generator strategies for non-numeric fields,
|
||||
OpenJPA also offers additional generator strategies for non-numeric fields,
|
||||
which you can access by setting <literal>strategy</literal> to <literal>AUTO
|
||||
</literal> (the default), and setting the <literal>generator</literal> string
|
||||
to:
|
||||
|
@ -851,9 +851,9 @@ to:
|
|||
uuid-string
|
||||
</primary>
|
||||
</indexterm>
|
||||
<literal>uuid-string</literal>: OpenJPA will generate a 128-bit UUID unique
|
||||
within the network, represented as a 16-character string. For more information
|
||||
on UUIDs, see the IETF UUID draft specification at:
|
||||
<literal>uuid-string</literal>: OpenJPA will generate a 128-bit type 1 UUID
|
||||
unique within the network, represented as a 16-character string. For more
|
||||
information on UUIDs, see the IETF UUID draft specification at:
|
||||
<ulink url="http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/">
|
||||
http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/</ulink>
|
||||
</para>
|
||||
|
@ -874,7 +874,48 @@ http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/</ulink>
|
|||
</primary>
|
||||
</indexterm>
|
||||
<literal>uuid-hex</literal>: Same as <literal> uuid-string</literal>, but
|
||||
represents the UUID as a 32-character hexadecimal string.
|
||||
represents the type 1 UUID as a 32-character hexadecimal string.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>
|
||||
mapping metadata
|
||||
</primary>
|
||||
<secondary>
|
||||
uuid-type4-string
|
||||
</secondary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>
|
||||
uuid-type4-string
|
||||
</primary>
|
||||
</indexterm>
|
||||
<literal>uuid-type4-string</literal>: OpenJPA will generate a 128-bit type 4
|
||||
pseudo-random UUID, represented as a 16-character string. For more
|
||||
information on UUIDs, see the IETF UUID draft specification at:
|
||||
<ulink url="http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/">
|
||||
http://www1.ics.uci.edu/~ejw/authoring/uuid-guid/</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>
|
||||
mapping metadata
|
||||
</primary>
|
||||
<secondary>
|
||||
uuid-type4-hex
|
||||
</secondary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>
|
||||
uuid-type4-hex
|
||||
</primary>
|
||||
</indexterm>
|
||||
<literal>uuid-type4-hex</literal>: Same as <literal> uuid-type4-string</literal>
|
||||
, but represents the type 4 UUID as a 32-character hexadecimal string.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
Loading…
Reference in New Issue