Creating a capped collection using Spring data MongoDB #Document - spring

I am trying out reactive support in spring-data with MongoDB. I am using spring-boot 2.0.0.
Generally I would write a domain object like this in my project:
#Document
public class PriceData {
......
}
With this spring-data it would create a collection with name priceData in MongoDB. If I want to customize it, then I would do it using the collection attribute:
#Document(collection = "MyPriceData")
Since I want to try reactive support of MongoDB, I want to create a capped collection so that I can use #Tailable cursor queries.
I can create a capped collection in my MongoDB database as specified here:
CollectionOptions options = new CollectionOptions(null, 50, true);
mongoOperations.createCollection("myCollection", options);
or
db.runCommand({ convertToCapped: 'MyPriceData', size: 9128 })
This is not a big problem if I use some external MongoDB database where I can just run this command once. But if I use an embedded MongoDB, then I would have put this in a class which would be executed every time during start up.
Either way I would be creating a collection even before the first request. So I was wondering if there is a way, I could specify to spring-data-mongodb that I need a capped collection instead of regular collection.
Unfortunately #Document doesn't help in this case.

So below is from Oliver
Might be a good idea to have those options exposed to the #Document annotation to automatically take care of them when building the mapping context but we generally got the feedback of people wanting to manually handle those collection setup and indexing operations without too much automagic behavior. Feel free to open a JIRA in case you'd like to see that supported nevertheless.
This is back in 2011. And it seems its still true to date. If you really need the change to handle it using annotation, you should open a JIRA ticket

Related

sparql queries in project

I have start working on project using SPARQL and springboot. How to managing very large SPARSQL queries? What is the right place to implement them in project? Currently I am just using methods with Springbuilder and returned a query as a String.
Constructing your queries as a String is fine, as long as you are very careful when injecting any user-provided input into your query.
A safer approach is to use a query builder, such as the RDF4J SparqlBuilder, so you can construct your queries in a fluent API, e.g. like this:
// SELECT ?product where { ?product a ex:book }
selectQuery.prefix(ex).select(product).where(product.isA(ex.iri("book"));
As for where to manage this stuff in your project, it depends a bit of the APIs you're using, but assuming you're using RDF4J, for example, I would typically recommend some variation of a DAO pattern, and creating your DAO class by means of a repository (connection) wrapper object.

HAL clients or examples of accessing HAL API

Question: Any HAL clients or examples of accessing HAL API with admin-on-rest ?
I got started because HAL was mentioned in the first paragraph of the introduction, but now I'm having trouble finding any examples or anyone else using HAL rest client, so I am winding up for now just writing a bunch of simple findAll repositories on top of the already robust existing HAL API.
Adding a more concise answer here that isn't polluted with my thought process now that I've got it all figured out (for anyone's future reference)... Again assuming the HAL API was made with Spring Data Rest.
The four major keys to this integration are:
Exposing foreign key attributes in your JPA entities, which is required in several places by admin-on-rest #Column(name="parentEntity", updatable=false, insertable=false) private Integer parentEntityId;
Exposing all your entity IDs using RepositoryRestConfiguration.exposeIdsFor( MyEntity.class )
Annotate your repositories as #RepositoryRestResource and have them extend PagingAndSortingRepository<MyEntity, Integer>, QueryDslPredicateExecutor<MyEntity> to expose extremely useful search filters by attribute name (e.g. /api/myEntitys?field1=foo&field2=bar).
When submitting create and save requests with foreign keys make sure to adjust your params.data to include the linked resource (e.g. 'http://myserver.com/api/myEntitys/19') on top of (or in place of, HAL has no use for it) the foreign key you exposed in 1. (e.g. myEntityId=19)
Other small items of note:
use PATCH instead of PUT when updating (you may be able to use PUT if you are more of a hibernate expert and can map your entities better than I can but I had trouble getting it mapped perfectly and HAL's PATCH will take partial entities)
When submitting GET_LIST and GET_MANY_REFERENCE you get the total number of items and pagination parameters from the 'page' section of the response, and you use 'size' and 'page' query params in your API requests. (so, no need for headers and stuff)
To change the default 'equals' filter for any string entries (from 3. above) to a 'contains' filter, you will have to also extend QuerydslBinderCustomizer<QMyEntity> and provide your own customize method in each of your repositories. For example:
default void customize( QuerydslBindings bindings, QChampion champion )
{
bindings.bind( String.class ).first( ( StringPath path, String value ) -> path.contains( value ) );
}
We don't have any examples for HAL specifically. However, the point of this introduction was that admin-on-rest is backend agnostic.
You can create your own custom rest client by following the documentation. Read the code of existing ones for inspiration.
For anyone referencing this in the future, if you happen to be in control of your API through Spring Data Rest you can consider the use of an excerptProjection on every one of your existing repositories that shows an inline version of your entity. This would work if there were absolutely nothing besides admin-on-rest accessing your API.
For my case I am planning on writing a custom projection for every rest resource that has entities and naming it the same thing: "inline". Then in the admin-on-rest restClient, just always asking for the inline projection on every GET_MANY or GET_MANY_REFERENCE request.
This is the best I have at the moment. It's not perfect but for the amount of entities I have it's still many weeks faster than building a CRUD interface from scratch so I highly recommend admin-on-rest.

What does Spring Data Couchbase use the _class field for?

I'm guessing that the type is used for CRUD operations. Is it used for anything else besides that? I'm wondering what impact there could be from configuring how it gets populated.
The _class field is written to allow polymorphic properties in your domain model. See this sample:
class Wrapper {
Object inner;
}
Wrapper wrapper = new Wrapper();
wrapper.inner = new Foo();
couchbaseOperations.save(wrapper);
You see how the field inner will get Foo serialized and persisted. On the reading side of things we now have to find out which type to create an object of and the type information in Wrapper is not enough to do so as it only states Object.
That's why Spring Data object mapping persists an additional field (name customizable but defaulting to _class) to store that information to be able to inspect the source document, derive a type from the value written for that field and eventually map that document back to that particular type.
The Spring Data Couchbase reference documentation doesn't really document it, you can find information about the way this works in the docs for the MongoDB module. I've also created a ticket for Spring Data Couchbase to improve on the docs for that.

spring-data-solr advanced nested model use case

I was given a task to introduce solr to our product so I thought about spring-data-solr. I have seen this blog:
http://www.petrikainulainen.net/spring-data-jpa-tutorial/
and I was able to run embedded solr in integration test. Since I have a simple POC I wanted to make it more advanced to see whether it fits our needs. So I started to search for mapping nested objects. I found this:
https://stackoverflow.com/questions/30561245/is-is-possible-to-use-embeddables-in-spring-data-solr
Someone answered that version 1.4.0 did not support nested objects. Anyone knows whether it changed? These links look promising:
https://dzone.com/articles/using-solr-49-new
Solr: Indexing nested Documents via DIH
https://issues.apache.org/jira/browse/SOLR-1945
So, wrapping up, here is a list of my questions:
Is it possible to map parent-child relation? (on one level at least?)
If you answered 'no' to first question - then how can I flatten child's fields to be part of solr's document? Should I register some kind of converter somehow? Is there anything else I should do?
I found also this: http://docs.spring.io/spring-data/solr/docs/current/api/org/springframework/data/solr/core/mapping/Indexed.html What is the purpose of this annotation? So far I have seen example with #Id and #Field annotations only. Is it used to generate schema based on model maybe? If so then how can I do that?
Last, but not least - when I create a SolrRepository should I use my JPA entity (annotated with #Fields annotations) as a generic type? Or rather should I create a totally different POJO which should be a view/dto of my jpa entity? This question is again about conversion I guess. If I create a dedicated POJO than I can convert/map fields manually in constructor, but this feels rather bad idea.

Use Spring Data mongodb to store XMLBeans as BSON objects

I am looking into using Spring Data mongodb and so far I like what I see. However, when I try to store more complicated objects, for example one created using APache XMLBeans, I get a StackOverFlowError. I think this is due to the cyclic nature of object refrences in the XMlBean. Does anyone have any suggestions as to a general way to store an XmlBean in mongodb as a BSON object that will allow for searching?
The solution does not need to use Spring.

Resources