Re: Using a time UUID as a sequence
Thanks for the reply Rick. That does the trick for one field, but this class is used heavily throughout the model. If possible I'd like to create a custom field mapping, so that every time a UUID is encountered, this mapping happens automatically.I've created a custom field mapping. public class UUIDValueHandler extends ByteArrayValueHandler { @Override public Object toDataStoreValue(ValueMapping vm, Object val, JDBCStore store) { final byte[] data = UUIDSerializer.toBytes((com.eaio.uuid.UUID) val); return super.toDataStoreValue(vm, data, store); } @Override public Object toObjectValue(ValueMapping vm, Object val) { byte[] data = (byte[]) val; final UUID uuid = UUIDSerializer.fromBytes(data); return uuid; } } However, it's not clear to me how to configure this as a plugin via the JPA configuration. I searched through the documentation, but I can't find any examples for how to do this. I referenced this section. http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#ref_guide_mapping_custom_field_conf However when I navigate to the reference of section 4 it takes me to this section. http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#ref_guide_mapping_defaults Should I define a property as follows? property name=openjpa.jdbc.MappingDefaults value=FieldStrategies='com.eaio.uuid.UUID=com.spidertracks.aviator.dataaccess.jpa.mysql.UUIDValueHandler'/ On 19 March 2014 08:56, Rick Curtis curti...@gmail.com wrote: Todd - Take a look at @Externalizer/@Factory in the user manual[1]. Below is a snippet of code where I have a String field in my Entity, but the backing column in the DB is an int. The Externalizer/Factory methods convert values from/to the database. Let me know how this goes. Thanks, Rick @Id @Externalizer(org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1.toDb) @Factory(org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1.fromDb) private String intField; public static int toDb(String val){ return Integer.valueOf(val); } public static String fromDb(int val) { return String.valueOf(val); } [1] http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#ref_guide_pc_extern On Wed, Mar 19, 2014 at 12:10 AM, Todd Nine t...@spidertracks.com wrote: Hi all, We're migrating from a Key/Value system to MySQL for some components of our system for easier administration and maintenance. As part of this migration, we need to retain the time UUIDs that have been generated for primary keys. I'm having a hard time mapping this. I have the following. @Id @Column( columnDefinition = BINARY(16), length = 16 ) private UUID id; However this always seems to fail. I'm on the latest MySQL version 5.6.16 GA and Open JPA 2.2.2 I've found this old thread, but it's not quite what I'm looking for. I'm really struggling to find the documentation on how to declare and implement custom type converters. Converting a UUID to a binary array of length 16 is trivial, as is creating a new UUID instance from those bytes. I'm just not sure how to plug in to the JPA framework to make it happen. Any advice would be greatly appreciated. Thanks, Todd -- *Rick Curtis*
Re: Using a time UUID as a sequence
Just to follow up my own email, my configuration in the persistence XML does work as expected. However, I'm receiving this error. Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: BLOB/TEXT column 'id' used in key specification without a key length {stmnt 992554479 CREATE TABLE AlertAcknowlege (id BLOB NOT NULL, createTime DATETIME, imeiNumber VARCHAR(255), queuedDate DATETIME, statusCode INTEGER, DTYPE VARCHAR(255), PRIMARY KEY (id)) ENGINE = innodb} [code=1170, state=42000] at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:247) Here is my mapping class. ** * The value handler for converting com.eaio.uuid.UUID objects to byte arrays. * * * @author Todd Nine */ public class UUIDValueHandler extends ByteArrayValueHandler { @Override public Object toDataStoreValue(ValueMapping vm, Object val, JDBCStore store) { final byte[] data = UUIDSerializer.toBytes((com.eaio.uuid.UUID) val); return super.toDataStoreValue(vm, data, store); } @Override public Object toObjectValue(ValueMapping vm, Object val) { byte[] data = (byte[]) val; final UUID uuid = UUIDSerializer.fromBytes(data); return uuid; } @Override public Column[] map(ValueMapping vm, DBIdentifier name, ColumnIO io, boolean adapt) { Column col = new Column(); col.setIdentifier(name); col.setJavaType(JavaSQLTypes.BYTES); //we should always be binary 16 for the uuid col.setType(Types.BINARY); col.setSize(UUIDSerializer.LENGTH); return new Column[]{ col }; } } As you can see on the type, I'm definitely setting the type to binary, and the length to 16 for every UUID type I encounter. Am I doing this incorrectly for the schema generation to work properly? Thanks, Todd On 19 March 2014 18:56, Todd Nine t...@spidertracks.com wrote: Thanks for the reply Rick. That does the trick for one field, but this class is used heavily throughout the model. If possible I'd like to create a custom field mapping, so that every time a UUID is encountered, this mapping happens automatically.I've created a custom field mapping. public class UUIDValueHandler extends ByteArrayValueHandler { @Override public Object toDataStoreValue(ValueMapping vm, Object val, JDBCStore store) { final byte[] data = UUIDSerializer.toBytes((com.eaio.uuid.UUID) val); return super.toDataStoreValue(vm, data, store); } @Override public Object toObjectValue(ValueMapping vm, Object val) { byte[] data = (byte[]) val; final UUID uuid = UUIDSerializer.fromBytes(data); return uuid; } } However, it's not clear to me how to configure this as a plugin via the JPA configuration. I searched through the documentation, but I can't find any examples for how to do this. I referenced this section. http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#ref_guide_mapping_custom_field_conf However when I navigate to the reference of section 4 it takes me to this section. http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#ref_guide_mapping_defaults Should I define a property as follows? property name=openjpa.jdbc.MappingDefaults value=FieldStrategies='com.eaio.uuid.UUID=com.spidertracks.aviator.dataaccess.jpa.mysql.UUIDValueHandler'/ On 19 March 2014 08:56, Rick Curtis curti...@gmail.com wrote: Todd - Take a look at @Externalizer/@Factory in the user manual[1]. Below is a snippet of code where I have a String field in my Entity, but the backing column in the DB is an int. The Externalizer/Factory methods convert values from/to the database. Let me know how this goes. Thanks, Rick @Id @Externalizer(org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1.toDb) @Factory(org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1.fromDb) private String intField; public static int toDb(String val){ return Integer.valueOf(val); } public static String fromDb(int val) { return String.valueOf(val); } [1] http://ci.apache.org/projects/openjpa/trunk/docbook/manual.html#ref_guide_pc_extern On Wed, Mar 19, 2014 at 12:10 AM, Todd Nine t...@spidertracks.com wrote: Hi all, We're migrating from a Key/Value system to MySQL for some components of our system for easier administration and maintenance. As part of this migration, we need to retain the time UUIDs that have been generated for primary keys. I'm having a hard time mapping this. I have the following. @Id @Column( columnDefinition = BINARY(16), length = 16 ) private UUID id; However this always seems to fail. I'm on the latest MySQL version 5.6.16 GA and Open JPA 2.2.2 I've found this old thread, but it's not quite what I'm looking for. I'm really struggling to find the documentation on how to declare
Using a time UUID as a sequence
Hi all, We're migrating from a Key/Value system to MySQL for some components of our system for easier administration and maintenance. As part of this migration, we need to retain the time UUIDs that have been generated for primary keys. I'm having a hard time mapping this. I have the following. @Id @Column( columnDefinition = BINARY(16), length = 16 ) private UUID id; However this always seems to fail. I'm on the latest MySQL version 5.6.16 GA and Open JPA 2.2.2 I've found this old thread, but it's not quite what I'm looking for. I'm really struggling to find the documentation on how to declare and implement custom type converters. Converting a UUID to a binary array of length 16 is trivial, as is creating a new UUID instance from those bytes. I'm just not sure how to plug in to the JPA framework to make it happen. Any advice would be greatly appreciated. Thanks, Todd
Re: Utilizing a slice for online migration
Hi Rick, Unfortunately I can't seem to use slice, since the Hector JPA plugin is not a JDBC based plugin. I'm now at the point of having 2 entity managers, 1 for Cassandra via Hector JPA, and another with MySQL. Do you know of anyone that has successfully implemented a proxy Entity Manager that can delegate to other entity managers? Our objects are always in a detached state, so we don't have to worry about transactions across both system. We're utilizing optimistic concurrency for all of our entities so this also should give us a bit of relief. Thanks in advance, Todd On 11 March 2014 07:04, Rick Curtis curti...@gmail.com wrote: Todd - Does anyone have any experience with using the policy in this manner? My general feeling is that not many people are using slice as there has been very little mailing list traffic regarding it's usage. Be sure to let us know how it goes! Thanks, Rick On Sun, Mar 9, 2014 at 12:54 PM, Todd Nine t...@spidertracks.com wrote: Hi all, We're migrating from a Cassandra based JPA adapter to Amazon's RDS. In order to do this, we want a no downtime migration. To do this, we would need the following flow. 1) Start writing to both systems. Cassandra is still the authoritative record, and records are replicated to RDS. All queries will still be served from Cassandra on read. 2) In the background, read all records from Cassandra and write them to RDS. Use update timestamps to ensure we don't overwrite newly updated data. 3) Switch our read path (probably with a new deployment configured to only read from RDS) I've been looking at the Slices documentation, and it seems like defining a Data Replication Policy will perform the dual writes I need in steps 1) and 2). Does anyone have any experience with using the policy in this manner? Thanks in advance, Todd -- *Rick Curtis*
Utilizing a slice for online migration
Hi all, We're migrating from a Cassandra based JPA adapter to Amazon's RDS. In order to do this, we want a no downtime migration. To do this, we would need the following flow. 1) Start writing to both systems. Cassandra is still the authoritative record, and records are replicated to RDS. All queries will still be served from Cassandra on read. 2) In the background, read all records from Cassandra and write them to RDS. Use update timestamps to ensure we don't overwrite newly updated data. 3) Switch our read path (probably with a new deployment configured to only read from RDS) I've been looking at the Slices documentation, and it seems like defining a Data Replication Policy will perform the dual writes I need in steps 1) and 2). Does anyone have any experience with using the policy in this manner? Thanks in advance, Todd
Re: Enhancement skipping field
Hey Rick, Adding the handler makes the field appear in the field list for my plugin. However my plugin currently doesn't support value handlers. I need to add this functionality, what is the best class to use as an example for reading this meta data and invoking it at runtime? Thanks, Todd On Tue, 2011-07-12 at 11:18 -0500, Rick Curtis wrote: Todd - I don't think the problem is that the enhancer skips the field, its the fact that we don't know how the map the UUID field. You might be able to write a customer value handler [1] ? Take a look at that and see if it would work for you. Let me know how it goes. [1] http://openjpa.apache.org/builds/latest/docs/manual/manual.html#ref_guide_mapping_custom_vhandler On Sun, Jul 10, 2011 at 3:12 PM, Todd Nine t...@spidertracks.com wrote: Hey guys, I'm also involved in this project, I'm the developer for this plugin. https://github.com/riptano/hector-jpa/ The UUID class is used extensively by quite a few Cassandra developers. We've successfully used it as an identity, and my plug in recognizes the data type and can correctly serialize it. However, when not used in either a composite identity or an identity, it appears that Open JPA does not correctly interpret the type and create an instance of a persistent UUID in the list of fields for the entity. Here is the UUID class we're using. http://johannburkard.de/software/uuid/ I definitely want to provide native support for this value in my plugin over string converter serialization. How can I get the open JPA enhancer to add it as a persistent field to the Entity during enhancement? I'll need to document this for my plugin, any help would be greatly appreciated. Todd On Fri, 2011-07-08 at 09:08 -0500, Rick Curtis wrote: Should your UUID class have an embeddable annotation also? On Thu, Jul 7, 2011 at 4:27 PM, Matthew Goodson matt...@spidertracks.co.nzwrote: Hi, Kevin: We're using maven and it is picking up the Phone_ class and generating the warning here's the link for the uuid class that we're using https://github.com/stephenc/eaio-uuid/blob/master/src/main/java/com/eaio/uuid/UUID.java And the persistence xml... persistence xmlns=http://java.sun.com/xml/ns/persistence; xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance; xsi:schemaLocation=http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd; version=2.0 persistence-unit name=openjpa providerorg.apache.openjpa.persistence.PersistenceProviderImpl/provider !-- base package -- classcom.spidertracks.aviator.model.Persistable/class classcom.spidertracks.aviator.model.UuidEntity/class !-- cluster -- classcom.spidertracks.aviator.model.cluster.ClusterRegion/class classcom.spidertracks.aviator.model.cluster.SpiderRegion/class !-- security -- classcom.spidertracks.aviator.model.security.AviatorRememberMeToken/class !-- sms -- classcom.spidertracks.aviator.model.sms.PhoneValidationMessage/class classcom.spidertracks.aviator.model.sms.ReceivedSmsMessage/class classcom.spidertracks.aviator.model.sms.SentSmsMessage/class classcom.spidertracks.aviator.model.sms.SmsMessage/class classcom.spidertracks.aviator.model.sms.SosClosedMessage/class classcom.spidertracks.aviator.model.sms.SosInvalidResponseMessage/class classcom.spidertracks.aviator.model.sms.SosMessage/class classcom.spidertracks.aviator.model.sms.SosTierOneMessage/class classcom.spidertracks.aviator.model.sms.SosTierOneReopenedUserMessage/class classcom.spidertracks.aviator.model.sms.SosTierTwoMessage/class classcom.spidertracks.aviator.model.sms.SosTierTwoReopenedUserMessage/class classcom.spidertracks.aviator.model.sms.SosTierTwoUserMessage/class !-- Sos -- classcom.spidertracks.aviator.model.sos.ContactedPerson/class classcom.spidertracks.aviator.model.sos.OpenHistory/class classcom.spidertracks.aviator.model.sos.SoS/class !-- spider -- classcom.spidertracks.aviator.model.spider.Spider/class !-- message -- classcom.spidertracks.aviator.model.spider.message.AlertAcknowlege/class classcom.spidertracks.aviator.model.spider.message.ConfigMessageUpdate/class classcom.spidertracks.aviator.model.spider.message.DistanceSettings/class classcom.spidertracks.aviator.model.spider.message.MobileTerminatedConfirmation/class classcom.spidertracks.aviator.model.spider.message.SpiderUpdate/class classcom.spidertracks.aviator.model.spider.message.SpiderwatchSettings/class classcom.spidertracks.aviator.model.spider.message.TimeDistanceSettings/class
Help with Embedded objects and statemanager detachment
Hi all, I'm having a very difficult time working with embedded entities in Cassandra. Specifically, this is the case where I'm getting very strange behavior.Em = Entity Manager. em created em begin transaction em load User entity , the embedded Address object is correct. em complete transaction User entity is now detached. Address is updated em begin transaction User is attached, and address is as well em.save(User) is invoked em flush em commit transaction The Address now has a null entity manager, and all fields are null, however it is correct when the entity was passed to the flush operation before using StateManager.get(fieldId) to retrieve the embedded object. For the Cassandra plugin in it's first implementation, we're requiring all @Embeddable entities to also implement Serializable. The embedded entity value is simply serialized to a column Here is the embedded column implementation I have created for @Embedded https://github.com/riptano/hector-jpa/blob/master/src/main/java/com/datastax/hectorjpa/meta/embed/EmbeddedColumnField.java Here is the implementation for @ElementCollection where the elements in the collection are @Embeddable https://github.com/riptano/hector-jpa/blob/master/src/main/java/com/datastax/hectorjpa/meta/embed/EmbeddedableCollectionColumnField.java Any guidance would be greatly appreciated. I know I'm not wiring the entity manager correctly during load, I'm just unsure what else I need to do. I've looked at both ElementEmbedValueHandler and EmbedFieldStrategy, however I'm not getting anywhere. Any help would be greatly appreciated. Thanks in advance! Todd
Overwriting currently loaded entity with new subclass using the same Id.
Hi all, I have a unique issue I could use a hand with. Our model uses the following inheritance Person - User - Customer. When purchases a unit and becomes a customer, they need to transparently be upgrade to a Customer. In doing so, I have to copy the UUID from the user to a customer. We can't change the UUID b/c it is referenced in other systems. Our storage system is functionally equivalent to single table inheritance. If I simply create a new instance and assign the same id, I receive this error. An object of type com.spidertracks.aviator.model.user.Customer with oid com.spidertracks.aviator.model.user.Customer-d81d5fe0-6195-11e0-861a-005056c8 already exists in this context; another cannot be persisted. The only way I've found around this is to perform the following steps. 1. load the original user, copy all the fields over that are not relationships (I.E *toMany *toOne). 2. Load all ids for entities that are related collections. 3. call entityManager.clear 4. Load all related collections 1 id at a time and link them to the new customer instance. 5. Call persist with the new customer. This is a bit of a pain, and as our entities get more complex this will be come messier. Is there an easier way to effectively deep copy the statemanager from one instance to another before persisting to avoid all these additional steps? Thanks, Todd