New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception while extracting child ValueObject (stored as Map value) #247

Closed
floresek opened this Issue Nov 10, 2015 · 7 comments

Comments

Projects
None yet
2 participants
@floresek

floresek commented Nov 10, 2015

Hi,

I have classes:

class Master {
    @Id
    String id;

    Map<String, Detail> details = new HashMap();

    public Master(String id) {
        this.id = id;
    }
}

@ValueObject
class Detail {
    String data;

    public Detail(String data) {
        this.data = data;
    }
}

and test code:

        Master master = new Master("1");
        master.details.put("key1", new Detail("detail-1"));
        master.details.put("key2", new Detail("detail-2"));
        javers.commit("anonymous", master);

Data are successfully committed to repository, but
while I read changes:

        List<Change> changes = javers
                .findChanges(QueryBuilder.byValueObjectId("1", Master.class, "detail")
                        .withNewObjectChanges(true)
                        .build());

I got an exception:

JaversException: CANT_EXTRACT_CHILD_VALUE_OBJECT JaVers runtime error - error while extracting child ValueObject from 'dto.Master.details', invalid property type, expected ValueObjectType or ContainerType<ValueObjectType>, got 'MapType{baseType:'java.util.Map<java.lang.String, dto.Detail>'}'
    at org.javers.core.metamodel.type.TypeMapper.getChildValueObject(TypeMapper.java:183)
    at org.javers.repository.jql.ValueObjectIdDTO.create(ValueObjectIdDTO.java:34)
    at org.javers.repository.jql.ValueObjectIdDTO.create(ValueObjectIdDTO.java:14)
    at org.javers.core.metamodel.object.GlobalIdFactory.createFromDto(GlobalIdFactory.java:77)
    at org.javers.repository.jql.QueryRunner.fromDto(QueryRunner.java:106)
    at org.javers.repository.jql.QueryRunner.queryForChanges(QueryRunner.java:74)
    at org.javers.core.JaversCore.findChanges(JaversCore.java:114)

Are you planning to add ValueObject as map value support?
It is very useful if you want to attach VO data to specific keys (identifying what has been changed).

Cheers
Mariusz

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Nov 11, 2015

it is supported, you need to add map key to path attribute in ValueObjectId,
use / as a separator

byValueObjectId("1", Master.class, "detail/key1")

I need to add docs for that ...

@floresek

This comment has been minimized.

floresek commented Nov 12, 2015

I wrote following test:

package test

import org.javers.core.JaversBuilder
import org.javers.repository.jql.QueryBuilder
import org.junit.Test

import javax.persistence.Id

class JaversTest {

    @Test
    void testMap() {
        def javers = JaversBuilder.javers().build()
        def obj = new Employee(
                name: '1',
                addressMap: [home:new Address(
                        city: 'city1'
                )]
        )

        javers.commit('test', obj)

        javers.findChanges(QueryBuilder.byValueObjectId(obj.name, Employee.class, "addressMap/home")
                .build());
    }

}

class Employee {
    @Id String name;
    Map<String,Address> addressMap;
}

class Address {
    String city;
}

and it fails :(:

DEBUG JaversBuilder - starting up JaVers ...
INFO  PropertyScannerModule - using FIELD mappingStyle
INFO  JaversBuilder - using fake InMemoryRepository, register actual implementation via JaversBuilder.registerJaversRepository()
INFO  JaversBuilder - JaVers instance is up & ready
INFO  TypeFactory - javersType of class test.Employee inferred as EntityType
INFO  TypeFactory - javersType of [class java.lang.String] inferred as ValueType, it's used as id-property type
INFO  TypeFactory - javersType of java.util.Map<java.lang.String, test.Address> inferred as MapType from prototype MapType{baseType:'interface java.util.Map'}
INFO  TypeFactory - javersType of class test.Address inferred as ValueObjectType
DEBUG ObjectGraphBuilder - live graph assembled, object nodes: 2, entities: 1, valueObjects: 1
DEBUG InMemoryRepository - 2 snapshot(s) persisted
INFO  Javers - Commit(id:1.0, snapshots:2, author:test, changes - NewObject:2)

JaversException: CANT_EXTRACT_CHILD_VALUE_OBJECT JaVers runtime error - error while extracting child ValueObject from 'test.Employee.addressMap', invalid property type, expected ValueObjectType or ContainerType<ValueObjectType>, got 'MapType{baseType:'java.util.Map<java.lang.String, test.Address>'}'
    at org.javers.core.metamodel.type.TypeMapper.getChildValueObject(TypeMapper.java:170)
    at org.javers.repository.jql.ValueObjectIdDTO.create(ValueObjectIdDTO.java:34)
    at org.javers.repository.jql.ValueObjectIdDTO.create(ValueObjectIdDTO.java:14)
    at org.javers.core.metamodel.object.GlobalIdFactory.createFromDto(GlobalIdFactory.java:72)
    at org.javers.repository.jql.QueryRunner.fromDto(QueryRunner.java:103)
    at org.javers.repository.jql.QueryRunner.queryForChanges(QueryRunner.java:73)
    at org.javers.core.JaversCore.findChanges(JaversCore.java:115)
    at org.javers.core.Javers$findChanges$0.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at test.JaversTest.testMap(JaversTest.groovy:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

I use 1.3.20 javers version

@bartoszwalacik bartoszwalacik added bug and removed fixed labels Nov 12, 2015

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Nov 12, 2015

right, sth is wrong here

bartoszwalacik added a commit that referenced this issue Nov 12, 2015

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Nov 13, 2015

fix is done in v 1.3.21, tomorrow morning it will be released to Central

@bartoszwalacik

This comment has been minimized.

Member

bartoszwalacik commented Nov 13, 2015

@floresek

This comment has been minimized.

floresek commented Nov 17, 2015

Excellent, thx ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment