javers CdoSnapshot.SnapshotType different from mssql to h2

164 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 answers

0
Bartek Walacik 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