diff --git a/hollow/src/main/java/com/netflix/hollow/core/write/objectmapper/HollowObjectTypeMapper.java b/hollow/src/main/java/com/netflix/hollow/core/write/objectmapper/HollowObjectTypeMapper.java index 7c1b21994b..f6cd961084 100644 --- a/hollow/src/main/java/com/netflix/hollow/core/write/objectmapper/HollowObjectTypeMapper.java +++ b/hollow/src/main/java/com/netflix/hollow/core/write/objectmapper/HollowObjectTypeMapper.java @@ -195,7 +195,11 @@ protected Object parseFlatRecord(HollowSchema recordSchema, FlatRecordReader rea if (schema.numFields() == 1 && schema.getFieldType(0) != HollowObjectSchema.FieldType.REFERENCE) { obj = mappedFields.get(0).parseBoxedWrapper(reader); } else { - obj = clazz.newInstance(); + try { + obj = clazz.newInstance(); + } catch (InstantiationException e) { + throw new IllegalStateException("Default constructor for class " + clazz.getName() + " not accessible", e); + } for (int i = 0; i < recordObjectSchema.numFields(); i++) { int posInPojoSchema = schema.getPosition(recordObjectSchema.getFieldName(i)); if (posInPojoSchema != -1) { diff --git a/hollow/src/test/java/com/netflix/hollow/core/write/objectmapper/HollowObjectMapperFlatRecordParserTest.java b/hollow/src/test/java/com/netflix/hollow/core/write/objectmapper/HollowObjectMapperFlatRecordParserTest.java index d1ca7b497b..5a6ee132dc 100644 --- a/hollow/src/test/java/com/netflix/hollow/core/write/objectmapper/HollowObjectMapperFlatRecordParserTest.java +++ b/hollow/src/test/java/com/netflix/hollow/core/write/objectmapper/HollowObjectMapperFlatRecordParserTest.java @@ -31,6 +31,66 @@ public void setUp() { mapper.getStateEngine(), new FakeHollowSchemaIdentifierMapper(mapper.getStateEngine())); } + static class V0 { + @HollowPrimaryKey(fields={"id"}) + private static class Movie { + private int id; + private String name; + int year; + + public Movie(int id, String name, int year) { + this.id = id; + this.name = name; + this.year = year; + } + } + } + + static class V1 { + @HollowPrimaryKey(fields={"id"}) + private static class Movie { + private String name; + private int id; + + public Movie() { } + + public Movie(String name, int id) { + this.name = name; + this.id = id; + } + } + } + + @Test + public void testSimpleSchemaEvolution() { + HollowObjectMapper mapper0 = new HollowObjectMapper(new HollowWriteStateEngine()); + mapper0.initializeTypeState(V0.Movie.class); + + FlatRecordWriter myFlatRecordWriter = new FlatRecordWriter( + mapper0.getStateEngine(), new FakeHollowSchemaIdentifierMapper(mapper0.getStateEngine())); + + V0.Movie actual = new V0.Movie(1, "Serde", 2023); + mapper0.writeFlat(actual, myFlatRecordWriter); + FlatRecord fr = myFlatRecordWriter.generateFlatRecord(); + + HollowObjectMapper myMapper1 = new HollowObjectMapper(new HollowWriteStateEngine()); + myMapper1.initializeTypeState(V1.Movie.class); + + V1.Movie expected = myMapper1.readFlat(fr); + Assert.assertEquals(expected.id, actual.id); + Assert.assertEquals(expected.name, actual.name); + } + + @Test (expected = RuntimeException.class) + public void testNoDefaultConstructor() { + HollowObjectMapper myMapper = new HollowObjectMapper(new HollowWriteStateEngine()); + myMapper.initializeTypeState(V0.Movie.class); + FlatRecordWriter myFlatRecordWriter = new FlatRecordWriter( + myMapper.getStateEngine(), new FakeHollowSchemaIdentifierMapper(myMapper.getStateEngine())); + FlatRecord fr = myFlatRecordWriter.generateFlatRecord(); + myMapper.readFlat(fr); + } + @Test public void testSimpleTypes() { TypeWithAllSimpleTypes typeWithAllSimpleTypes = new TypeWithAllSimpleTypes();