Using Orika in place of Spring Data Commons - orika

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

Related

Search in state column in javers snapshot table

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?

Spring Data Rest ignoring #JsonInclude annotation

With or without this annotation, there is a property on my JPA #Entity
#Entity
public class Myentity extends ResourceSupport implements Serializable {
...
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="idrepository")
#JsonInclude(JsonInclude.Include.ALWAYS)
private MyentitySource entitysource;
...
}
that is not being mapped when I return:
#RequestMapping("/myentity/{uuid}")
public ResponseEntity<Myentity> getResourceById(#PathVariable("uuid") UUID uuid) {
Myentity result = myentityRepository.findOne(uuid);
return ResponseEntity.ok(myentityAssembler.toResource(result));
}
myentityAssembler.toResource(result) does contain this MyentitySource entitysource, but the JSON output does not.
The weirdest thing is I have another spring boot hateoas project where I am using the exact same entity, repository, controller, and assembler implementations, with the exact same dependencies and versions on my pom, and a very similar configuration (I am not defining any special jackson mappers or anything, just using the default rest/hateoas configuration), and it does work there: The MyentitySource entitysource property, which is another JPA entity extending ResourceSupport, gets serialized and included into the JSON output.
I have been a couple of hours at it already, but I am quite lost. I have verified this behavior is happening all through the application in both applications: #ManyToOne relations defined on any #Entity are being mapped and present in the JSON output on one application, but not in the other.
How can I get these fields to show up on the JSON output?
entitysource will be included if MyentitySource is not an exported entity. If it is one - what seems to be the case here - then it would be wrong to include it. Including associations could lead to sending the whole database to the client. Moreover it is a separate resource with its own URI. Consequently a link to that URI is included in the response.
CascadeType.ALL implies that Myentity is an aggregate, therefore MyentitySource should not be exported in the first place. That would solve your problem. If my assumption is wrong, then you can still use Projections to get entitysource included. I can refer you to this answer from Spring's Oliver Gierke and the relevant chapter of the documentation.

I have ontology file which i have created using Protege.. Want to retrieve classes and properties

I have ontology file which i have created using Protege.. For my java application i need to retrieve classes and their properties.. I have tried following code but it retrieves only tripples.. I m new to Jena Api and Ontology so pls help
String URI = "http://www.semanticweb.org/ontologies/2012/0/SBIRS.owl";
String inputFileName = "D:\\SBIRS.owl";
System.out.println("File Name" + inputFileName);
OntModel model = ModelFactory.createOntologyModel();
StmtIterator si=model.listStatements();
ResIterator iter=model.listSubjects();
while(iter.hasNext())
{
Resource res=iter.nextResource();
System.out.println("Property==>" + res.getProperty(null).toString());
System.out.println("Resource URI==>" + res.getURI());
}
To list the classes in an OntModel, use the listClasses method. Each returned result from that method will be an instance of the Java class OntClass, which provides convenient access to the triples from the underlying model which define the class.
When you say you need to retrieve "classes and their properties", you could mean two things: the RDF properties of the RDF resource that denotes the class, or the properties which are typically used with instances of the class. In the first case, you can get these through the API on OntClass (and its Java super-classes, e.g. Resource). In the second case, you need to read this how-to.

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)

NHibernate: How to get mapped values?

Suppose I have a class Customer that is mapped to the database and everything is a-ok.
Now suppose that I want to retrieve - in my application - the column name that NH knows Customer.FirstName maps to.
How would I do this?
You can access the database field name through NHibernate.Cfg.Configuration:
// cfg is NHibernate.Cfg.Configuration
// You will have to provide the complete namespace for Customer
var persistentClass = cfg.GetClassMapping(typeof(Customer));
var property = persistentClass.GetProperty("FirstName");
var columnIterator = property.ColumnIterator;
The ColumnIterator property returns IEnumerable<NHibernate.Mapping.ISelectable>. In almost all cases properties are mapped to a single column so the column name can be found using property.ColumnInterator.ElementAt(0).Text.
I'm not aware that that's doable.
I believe your best bet would be to use .xml files to do the mapping, package them together with the application and read the contents at runtime. I am not aware of an API which allows you to query hibernate annotations (pardon the Java lingo) at runtime, and that's what you would need.
Update:
Judging by Jamie's solution, NHibernate and Hibernate have different APIs, because the Hibernate org.hibernate.Hibernate class provides no way to access a "configuration" property.