SpecificData#deepCopy will make this conversion. It currently fails for enums, but the fix is easy. Here's a patch that makes that fix and demonstrates a conversion. If this change is of interest, please file an issue in Jira.
Doug Index: lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java =================================================================== --- lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java (revision 1564561) +++ lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java (working copy) @@ -933,8 +933,7 @@ case DOUBLE: return (T)new Double((Double)value); case ENUM: - // Enums are immutable; shallow copy will suffice - return value; + return (T)createEnum(value.toString(), schema); case FIXED: return (T)createFixed(null, ((GenericFixed) value).bytes(), schema); case FLOAT: Index: lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificData.java =================================================================== --- lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificData.java (revision 1564561) +++ lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificData.java (working copy) @@ -40,6 +40,8 @@ import org.apache.avro.test.MD5; import org.apache.avro.test.Kind; +import org.apache.avro.generic.GenericRecord; + public class TestSpecificData { @Test @@ -95,6 +97,16 @@ new SpecificDatumReader<Object>()); } + @Test public void testConvertGenericToSpecific() { + GenericRecord generic = new GenericData.Record(TestRecord.SCHEMA$); + generic.put("name", "foo"); + generic.put("kind", new GenericData.EnumSymbol(Kind.SCHEMA$, "BAR")); + generic.put("hash", new GenericData.Fixed + (MD5.SCHEMA$, new byte[]{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5})); + TestRecord specific = + (TestRecord)SpecificData.get().deepCopy(TestRecord.SCHEMA$, generic); + } + @Test public void testGetClassSchema() throws Exception { Assert.assertEquals(TestRecord.getClassSchema(), TestRecord.SCHEMA$); Assert.assertEquals(MD5.getClassSchema(), MD5.SCHEMA$); On Thu, Feb 6, 2014 at 8:12 AM, Christophe Taton <christophe.ta...@gmail.com> wrote: > I believe we could eventually make a generic function that can rewrite any > record or record builder, whether specific or generic, into another record > or record builder, whether specific or generic. > > Until this happens, Mika's suggestion is probably the best short-term > solution. > > C. > > > On Wed, Feb 5, 2014 at 2:59 PM, Roger Hoover <roger.hoo...@gmail.com> wrote: >> >> Hi Christophe, >> >> Thanks for your reply. When you say that we could write a generic >> conversion function, do you mean we can write one that works for all >> schemas? That would be great! >> >> I'd like an API something like this: >> >> MyCustomRecord record = MyCustomRecord.newBuilder(GenericRecord >> record).build() >> >> Thanks, >> >> Roger >> >> >> On Wed, Feb 5, 2014 at 10:59 AM, Christophe Taton >> <christophe.ta...@gmail.com> wrote: >>> >>> Hi Roger, >>> With the change proposed in >>> https://issues.apache.org/jira/browse/AVRO-1443, you would be able to create >>> a specific record using a generic builder API. That means we could write a >>> generic conversion function that creates specific records. >>> Would that work for you? >>> C. >>> >>> >>> On Wed, Feb 5, 2014 at 10:23 AM, Roger Hoover <roger.hoo...@gmail.com> >>> wrote: >>>> >>>> Hi, >>>> >>>> I'm working with an existing API that hands me a GenericRecord. Is >>>> there an easy way I can covert it into a SpecificRecord. Really I want to >>>> get it into the code-generated object. >>>> >>>> Thanks, >>>> >>>> Roger >>>> >>>> >>> >> >