javers CdoSnapshot.SnapshotType different from mssql to h2

196 Views Asked by At

I try to audit an object. My problem is, I get not on every database the same result.

My entity:

public class Person {

    @Id
    private String login;
    private String name;

    public Person(String login, String name) {
        this.login = login;
        this.name = name;
    }

    public String getLogin() {
        return login;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The test method:

@Test
public void testperson() throws SQLException {
    Person entity = new Person("bob", "Robert Martin");
    javers.commit("user", entity);

    entity.setName("Robert C.");
    javers.commit("user", entity);

    entity.setName("Robert B.");
    javers.commit("user", entity);

    List<CdoSnapshot> snapshots = javers.findSnapshots(QueryBuilder.byInstanceId("bob", Person.class).build());

    snapshots.forEach(a -> System.out.println(a.getType().toString()));
}

On mssql with openjpa my systemout looks like this:

UPDATE

INITIAL

INITIAL

On H2 the result looks different:

UPDATE

UPDATE

INITIAL

I would say the first output is wrong. Isn’t it? Why are they different. What I do wrong?

I created javers for mssql so:

@Before
public void setUp() {
    JaversSqlRepository sqlRepository = SqlRepositoryBuilder.sqlRepository().withConnectionProvider(connectionProvider).withDialect(DialectName.MSSQL).build();
    javers = JaversBuilder.javers().registerJaversRepository(sqlRepository).build();
}

ConnectionProvider connectionProvider = new ConnectionProvider() {
    @Override
    public Connection getConnection() {
        OpenJPAEntityManager kem = OpenJPAPersistence.cast(entityManager);
        return (Connection) kem.getConnection();
    }
};

And for h2:

@Before
public void setUp() {
    JaversSqlRepository sqlRepository = SqlRepositoryBuilder.sqlRepository().withConnectionProvider(connectionProvider).withDialect(DialectName.H2).build();
    javers = JaversBuilder.javers().registerJaversRepository(sqlRepository).build();
}

ConnectionProvider connectionProvider = new ConnectionProvider() {
    @Override
    public Connection getConnection() {
        return dbConnectionh2;
    }
};

Any idea?

Thank you

Update:

If I use mssql without openjpa:

private final Connection localhostConnection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=aDatabase;user=*******;password=********");

@Before
public void setUp() {
    JaversSqlRepository sqlRepository = SqlRepositoryBuilder.sqlRepository().withConnectionProvider(connectionProvider).withDialect(DialectName.MSSQL).build();
    javers = JaversBuilder.javers().registerJaversRepository(sqlRepository).build();
}

ConnectionProvider connectionProvider = new ConnectionProvider() {
    @Override
    public Connection getConnection() {
        return localhostConnection;
    }
};

It works as expected.

UPDATE

UPDATE

INITIAL

Have I done something wrong with openjpa?

Update 2 I extend my test case with another entity (bob1):

@Test
public void testPerson() throws SQLException {
    Person entity = new Person("bob", "Robert Martin");
    javers.commit("user", entity);

    entity.setName("Robert C.");
    javers.commit("user", entity);

    entity.setName("Robert B.");
    javers.commit("user", entity);

    Person entity1 = new Person("bob1", "Robert Martin");
    javers.commit("user", entity1);

    entity1.setName("Robert C.");
    javers.commit("user", entity1);

    entity1.setName("Robert B.");
    javers.commit("user", entity1);
}

The table jv_snapshot in the mssql has now the following records:

snapshot_pk  type     version  global_id_fk
0            INITIAL  1        0
1            INITIAL  1        0
2            UPDATE   2        0
3            INITIAL  1        1
4            UPDATE   2        1
5            UPDATE   3        1

The first entity has a wrong second type (initial) and also has a wrong version. The second entity looks ok for me.

Is it a bug?

1

There are 1 best solutions below

0
On

Seems like your application and javers are using different db connections (and transactions). Javers doesn't have integration support for openjpa. It means that you need to implement transaction-aware ConnectionProvider (as described in https://javers.org/documentation/repository-configuration/#connection-provider)

See how it's done for Hibernate: https://github.com/javers/javers/blob/master/javers-spring/src/main/java/org/javers/spring/jpa/JpaHibernateConnectionProvider.java