Search in state column in javers snapshot table - sql

I am new in javers so my question is maybe silly. I have a java spring application and I have pulled javers version 6.8.2 in. I can save my entities properly and at the same time javers saves the state of my entity in it's table structure. But whenever I try to query historical information I fail. I want to get all the historical data related to a few fields' values. Let me give you an example:
I have the following java entity (I avoid to add jpa annotations here)
public class DummyClass {
String field_1;
Integer field_2;
OffsetDateTime field_3;
List<Integer >field_4;
}
#Repository
#JaversSpringDataAuditable
public interface DummyClassRepository extends JpaRepository<DummyClass, String> {}
I can persist my entity in Javers repository into jv_snapshot table. My entity's structure saved under "state" column in jv_snapshot table in json format. Here is my jv_snapshot table column list:
snapshpt_pk;
type;
state;
changed_properties;
managed_type;global_id_fk;
commit_fk;
And here is the way how my data was persisted:
column state:
{
"field_1": "XXXXX",
"field_2": "wwww",
"field_3": "2022-12-20T02:46:00.540",
"field_4": "zzz"
}
Now I want to get back all of my hystorical records, especially I want to get back all of the domain objects (using the original java class) where a certain domain object's fields carrying a certain value.
So for instance I want to see all of my entities where field_1=XXXXX and field_3>2021-12-20T02:46:00.540.
Is there any way I can achive this in javers?

Related

Sulu: Entity has no field or association error

I'm following Sulu example here: https://github.com/sulu/sulu-workshop/
trying to set translations for custom entity type.
My entity file has getter for field "home_team" defined like:
/**
* #Serializer\VirtualProperty(name="home_team")
*/
public function getHomeTeam(): ?string
{
$translation = $this->getTranslation($this->locale);
if (!$translation) {
return null;
}
return $translation->getHomeTeam();
}
So field is not actually part of that entity, but of it's translation entity since it suppose to be translatable.
When I try to create new object of that entity type it works well. I can see in database that field values are stored well and I don't get any error.
But on overview page instead of list of all objects I get error:
[Semantical Error] line 0, col 73 near 'home_team AS': Error: Class App\Entity\MatchEvent has no field or association named home_team
Any idea what could be wrong here?
If you wanna see the translation in the listView you have to create a real translationEntity, like in the workshop project. In this post it is already explained, how to translate a custom entity correctly.
If you have already created your translationEntity you have to configure the relation of the translation to your main entity via a join. Here is an example in the workshop for this configuration.
Sulu uses optimised queries to create the list-object directly from the database. So the entity itself does not get hydrated or serialised for performance reasons. Thus your virtualProperty is never executed.

RepoDb cannot find mapping configuration

I'm trying to use RepoDb to query the contents of a table (in an existing Sql Server database), but all my attempts result in an InvalidOperationException (There are no 'contructor parameter' and/or 'property member' bindings found between the resultset of the data reader and the type 'MyType').
The query I'm using looks like the following:
public Task<ICollection<MyType>> GetAllAsync()
{
var result = new List<MyType>();
using (var db = new SqlConnection(connectionString).EnsureOpen())
{
result = (await db.ExecuteQueryAsync<MyType>("select * from mytype")).ToList();
}
return result;
}
I'm trying to run this via a unit test, similar to the following:
[Test]
public async Task MyTypeFetcher_returns_all()
{
SqlServerBootstrap.Initialize();
var sut = new MyTypeFetcher("connection string");
var actual = await sut.GetAllAsync();
Assert.IsNotNull(actual);
}
The Entity I'm trying to map to matches the database table (i.e. class name and table name are the same, property names and table column names also match).
I've also tried:
putting annotations on the class I am trying to map to (both at the class level and the property level)
using the ClassMapper to map the class to the db table
using the FluentMapper to map the entire class (i.e. entity-table, all columns, identity, primary)
putting all mappings into a static class which holds all mapping and configuration and calling that in the test
providing mapping information directly in the test via both ClassMapper and FluentMapper
From the error message it seems like RepoDb cannot find the mappings I'm providing. Unfortunately I have no idea how to go about fixing this. I've been through the documentation and the sample tutorials, but I haven't been able to find anything of use. Most of them don't seem to need any mapping configuration (similar to what you would expect when using Dapper). What am I missing, and how can I fix this?

Using Orika in place of Spring Data Commons

There are several Spring Data projects like Neo4j that use the Spring Data Commons to build up a PersistentEntity/PeristentProperty (basically type info plus property geters and setters) and EntityConverter to roll from a native store to Java. This is what the SDN (Spring Data Neo4j) does plus it bundling BeanWrapper converters to make sure that certain property types are allowed for the Neo4j data structure.
Basically Java beans are stamped with a #NodeEntity annotation and the beans is decomposed on writes into nodes (think a bean with only simple properties) interlinked by relationship objects.
Wondering if I can do the same with Orika? Means identifying classes via an annotation and processing each property when complex recursively. For example:
#NodeEntity
class Software {
String name;
....
Organisation organisation;
....
}
#NodeEntity
class Organisation {
String name;
}
Should be rolled into 2 nodes each containing the property name and a relationship object (denotes Organisation as a member of Software).
Here is an example of an Orika ClassMapBuilder supporting custom annotations, I think you can adapt it to meet your needs.
Gist : AnnotationClassMapBuilder
For Node (or DBObject of MongoDB) you can use a custom property resolver, take a look at:
http://orika-mapper.github.com/orika-docs/advanced-mappings.html (ElementPropertyResolver)
Edit
Orika build mappers by class-map which are actually, just a collection of property-pair, property can be any thing which has name, type and setter or/and getter.
You can automatically create for each attribute in your beans an equivalent in Neo4J side, and let Orika build the mapper.
For example you can create a Person(name)->PrintStream mapper,
in which you create for each person's property (name) an equivalent that print data (System.out)
Example
final Builder name = new Property.Builder()
.name("name")
.type(String.class.getName())
.setter("append(\"My name : \").append(%s).append('\\n')");
factory.classMap(Person.class, PrintStream.class).fieldMap("name", name, false).add().register();
factory.getMapperFacade().map(person, System.out); // This print to default output stream, My name : xxxx

How to display only specific columns of a table in entity framework?

how to display the some specific columns of table instead of whole table in entity framework.
using (DataEntities cxt = new DataEntities())
{
notes note = cxt.notes.Where(no => no.id == accID).SingleOrDefault();
return notes;
}
For this purpose, I would suggest you to make use of ViewModel like following :-
notes note = cxt.notes.SingleOrDefault(no => no.id == accID);
var model = new YourViewModel // Your viewModel class
{
ID = note.ID,
PropertyOne = note.PropertyOne, // your ViewModel Property
PropertyTwo = note.PropertyTwo
};
You can do this with QueryView.
This implies editing your model directly in XML as there is no designer support for this, but you will get an independant entity with less fields than the original one.
Advantages:
You can then query data base for this truncated entity directly (you will get only fields you need from the data base - no need to get whole entity from DB and trancate it in code)
It is good in scenarios where you want to send this truncated entity to the
client
with WCF to minimize traffic (e.g. when building big lists on client
that basically need only name and ID and no other entity specific
information).
Disadvantages:
This QueryView-based entity is read only. To make it writeable you will have to add r/w functionality yourself

Entity Framework 4.1 Dynamically retrieve mapped column name

I am trying to construct an SQL statement dynamically.
My context is created dynamically, using reflection finding classes deriving from EntityTypeConfiguration and adding them to DbModelBuilder.Configuration.
My EntityTypeConfiguration classes specify HasColumnName to map the Entity property name to db table column name, which I need to construct my SQL statement.
namespace MyDomain {
public class TestEntityConfig : EntityTypeConfiguration<TestEntity>{
Property("Name").HasColumnName("dbName");
}
}
From What I have researched, it seems I can get access to this information through MetadataWorkspace, which I can get to through ObjectContext.
I have managed to retrieve the the entity I am interested in with MetadataWorkspace.GetItem("MyDomain.TestEntity",DataSpace.OSpace), which gives me access to Properties, but none of the properties, of Properties, give me the name of the mapped db column, as specified with HasColumnName.
Also I am not clear what DataSpace.OSpace is and why my model is constructed in this space.
If Anyone can shed some light on this I would be grateful
UPDATE
Further to #Ladislav's comments. I discovered I can get the information as follows
For the class properties
ctx.MetadataWorkspace.GetItem<ClrEntityType>("MyDomain.TestEntity", DataSpace.OSpace)).Members
For the table properties
ctx.MetadataWorkspace.GetItem<EntityType>("CodeFirstDatabaseSchema.TestEntity",SSpace).Members
So given that I only know the type MyDomain.TestEntity and Memeber "Name". How would I go about to get "dbName". Can I always assume that my mapped class will be created in CodeFirstDatabaseSchema, om order to dynamically construct the identity to retrieve it from SSpace and how would I get to the correct Member in SSpace. Can I do something like
var memIndex = ctx.MetadataWorkspace.GetItem<ClrEntityType>("MyDomain.TestEntity", DataSpace.OSpace)).Members["Name"].Index;
var dbName = ctx.MetadataWorkspace.GetItem<EntityType>("CodeFirstDatabaseSchema.TestEntity",SSpace).Members[memIndex];
MetadataWorkspace contanis several containers specified by DataSpace. Interesting for you are:
CSpace - description of conceptual model (this should contain properties)
CSSpace - mapping of conceptual model to storage model (this should contain how classes / properties are mapped to tables / columns)