How to output contents of _aud table as JSON? - spring-data-jpa

I would like to display the contents of my _aud table in a JSON array like this:
[
{
"id":1,
"rev":1,
"revtype":0,
"created_date":xxxx,
"modified_date":yyyy
}
]
How do I write my controller GET method?
I had written something like this:
#GetMapping("/audit/{id}")
public List<Revisions<Long, Person>> getRevisions(#PathVariable("id") long id) {
return personRepository.findRevisions(id);
}
Unfortunately Spring Boot/Jackson cannot convert Revisions to JSON.
How do I view the records from the _aud table as a JSON array?
I am using Spring Data Envers and my repository class implements RevisionRepository<Person, Long, Long>.

Related

Spring Data MongoDB - Is there a way to have an implicit timestamp?

Using my MongoDB and Spring Data MongoDB I am currently looking for a timestamp to be visible in the collection documents.
For now the document looks like this:
{
"_id":"f84fd693-e04b-4acb-9390-32ee755c1506",
"name":"Herbert",
"age":{"$numberInt":"21"},
"_class":"com.alemannigame.backend.domain.Character"
}
However I'd like to have a "timestamp": "1988-03-12T02:30:12+00:00" (example format) in it as well. Is there a way to do so without having to write logic in a Service to actually add a timestamp manually?
I thought about something like:
#Document(withTimestamp: true) // this
data class Character(
#Id
val id: String,
val name: String,
val age: Int
)
Could not find anything similar in the interwebs! Nifty solutions are welcome!
So I found something out about Lifecycle Events for Spring Data MongoDB (https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.aggregation).
This gave me several interceptors before a document is saved to MongoDB.
It's very straight forward to use. I chose the onBeforeConvert hook so I can manipulate my model before it is being saved.
As you can see I added the timestamp of the event to my source instance. I like Unix timestamps and since the event object already has that ready I reused it.
#Component
class MongoSaveInterceptor : AbstractMongoEventListener<Character>() {
override fun onBeforeConvert(event: BeforeConvertEvent<Character>) {
val source = event.source
source.timestamp = event.timestamp
}
}
When using MongoDB's implicit ObjectId (which I do not - I use an own UUID id) I think that event.timestamp is used here.

Morphia - Map single collection data into multiple pojos

I have a collection with 40 fields.
I have pojo as follows
#Entity("colName")
public class Entity1 {
//Id
//10 fields - names same as collection columns
#Embedded
//Entity2
}
Entity2 class:
#Embedded
public class Entity2 {
//20 other fields
}
I query the collection as follows
datastore.createQuery(Entity1.class).disableValidation().filter("fieldFromEntity1", "2227536").asList();
But I get always Entity2 reference as null.
I found that Entity2 has to be nested document.
Is there any way to achieve this?
Document:
{
_id: a|b|c,
field1: stringValue,
....
field40: intgerValue
}
Morphia doesn't directly support what you need. However, you can use #Preload and #Presave to manipulate the shapes of documents on their way to/from the database. I think you could also just use, say, Jackson annotations to name/nest those fields when serializing out to json. That'd be the simplest approach.

Get Discriminator in Linq Select results

I'm trying to make a SQL Query with LinqToEntities which will be as efficient as possible so I would like to avoid iterating after every record I get in results to get a new corrected collection. I'm trying to create a ready collection to send as a result in API just with this one query.
I'm trying to get a discriminator value though with inherited models.
My models are somewhat like these:
public abstract class DbEntity
{
[NotMapped]
public string DiscriminatorValue
{
get
{
return ObjectContext.GetObjectType(GetType()).Name;
}
}
}
public class Foo : DbEntity {
}
public class Bar: DbEntity {
}
This model will create a table in database which will have a column called Discriminator. To get the discriminator value I used my custom DiscriminatorValue property but it won't work in queries like this:
var events = context.MyTable.Select(t => new {
Discriminator = t.DiscriminatorValue
}).ToList();
This below one will obviously work, but it will be much slower imho:
var events = context.MyTable.ToList().Select(t => new {
Discriminator = t.DiscriminatorValue
}).ToList();
Is it possible to get Discriminator value without having to write my custom SQL query myself (like real sql which I know is possible too).

Saving enum into mongoDB

Is there a way to save enum into the mongoDB? I want to save something like:
public enum SnapshotType {
EVENT,
MEMORY
}
I assume you mean saving an enum value into a collection.
Basically, you just add it into your entity model, like so:
#Document(collection = "MyEntity ")
public class MyEntity {
public SnapshotType snapshotType;
}
It will store it as a string in mongo, and automagically convert when you read it out.
Just save the result. There are no schemas in mongo.

Having a list of strings represented in a database using ORMLite

First of I am new to ORMLite. I would like my model class to have a field which is a list of strings, that would eventually hold a list of tags for my model object.
Which ORMLite annotations should I use?
Firstly I don't want to have a table of all tags, and then use the #ForeignCollectionField.
Also I thought of using the #DatabaseField(dataType=DataType.SERIALIZABLE) annotation, but it turns out that List<String> doesn't implement the Serializable interface.
What are your suggestions?
First of all, List doesn't implement Serializable but ArrayList certainly does as well as most of the common collection implementations. But storing a huge list is probably not the best of doing this from a pure object model standpoint.
So why don't you want to have a table of all tags? That's the best way from a pure model standpoint. It will require a 2nd query if you need them every time. That's the way hibernate would store a list or array of tags.
After reading your comment #creen, I still think you do want a table of tags. Your model class would then have:
#ForeignCollectionField
Collection<Tag> tags;
The tags table would not have a single tag named "red" with multiple model classes referring to it but multiple "red" entries. It would look like:
model_id name
1 "red"
1 "blue"
2 "red"
3 "blue"
3 "black"
Whenever you are removing the model object, you would first do a tags.clear(); which would remove all of the tags associated with that model from the tags table. You would not have to do any extra cleanup or anything.
No need to go for #ForeignCollectionField for simple String Array
Change your code
#DatabaseField(dataType=DataType.SERIALIZABLE)
List<String> users;
to
#DatabaseField(dataType = DataType.SERIALIZABLE)
String[] users;
Database doesn't want to store dynamically grow able arrays. That is the reason it allows only static array like string[] and not List.
I added two properties... one that gets written to the database as a csv string and the other that translates this:
[Ignore]
public List<string> Roles
{
get
{
return new List<string>(RolesCsv.Split(new char[] { ',' }));
}
set
{
RolesCsv = string.Join(",", value);
}
}
public string RolesCsv { get; set; }