Advanced spring-data query/critera - spring-data-mongodb

I have been building a Spring based REST service using MongoDB and Spring Data - MongoDB.
See below; parts of my data model:
#Document
public class User{
.....
private List<EMail> emails;
.....
}
public class EMail {
.....
private bool defaultMail;
private String eMailAdress;
.....
}
EMail is not annotated as a MongoDb Document.
I would like to achieve following functions in the Repository.
public Boolean exists(String email);
public User getUserByEmail(String email);
I can implement simple queries using Query and the Criteria API, but have not been successful achieving above functions.

I found a answer on my own question and I would like to share.
The query should look like this:
query (where("emails").elemMatch(where("eMailAdress").is(email)))
I found the answer by reading MongoDb manual,,, which turns out is much more understandable than spring-data manual.
//lg

Related

Retrieve Max value from a field using Spring Data and MongoDB

I want to obtain the maximum value of the field code within my User entity, using Spring Data and MongoDB.
I have seen similar examples using as below,
".find({}).sort({"updateTime" : -1}).limit(1)"
But have no idea how to integrate it into my own repository using the #Query annotation.
Any alternative solution, than to return the maximum value of said field is also welcome.
Thank you.
You can write a custom method for your repository.
For example you have:
public interface UserRepository extends MongoRepository<User, String>, UserRepositoryCustom {
...
}
Additional methods for repository:
public interface UserRepositoryCustom {
User maxUser();
}
And then implementation of it:
public class UserRepositoryImpl implements UserRepositoryCustom {
#Autowired
private MongoTemplate mongoTemplate;
#Override
public User maxUser() {
final Query query = new Query()
.limit(1)
.with(new Sort(Sort.Direction.DESC, "updateTime"));
return mongoTemplate.findOne(query, User.class)
}
}
You can use the spring data method syntax like:
public User findTopByOrderByUpdateTimeAsc()
A reference can be found here: https://www.baeldung.com/jpa-limit-query-results#1first-ortop
Use this code in spring to get the latest updated time from mongodb: (mongoTemplate)
public List getTopPosts() {
Query query = new Query();
query.with(Sort.by(Sort.Direction.DESC, "postUploadedTime"));
return mongoTemplate.find(query,Post.class);
}

Does Spring Data REST support adding custom behavior to single repositories with Spring Data MongoDB?

Does Spring Data REST support adding custom behavior to single repositories with Spring Data MongoDB and exposing it as a rest resource?
For example, here is the pojo:
#Document
#Data
#EqualsAndHashCode
public class Poet {
#Id
private String id;
private String title;
private String author;
private String content;
}
And Here is the repository:
#CrossOrigin
#RepositoryRestResource
public interface PoetRepository extends MongoRepository<Poet, String>, MyPoetRepository {
}
Can I find all the distinct title attribute in the document poet by extending a custom interface? By the way, how to implement the custom interface?

Bean Validation and Objectify

I'm using Objectify to manage GAE Datastore persistence. I cannot find much useful documentation on Bean validation using Objectify. I tried using the Hibernate Validator, but it still allows me to persist invalid data.
To make things crystal clear, here's a simple example:
#Entity
public class Person {
#Id Long id;
// validate firstName is 1-20 characters, like Hibernate's #Length(min=1, max=20) annotation
#Index private String firstName;
// GETTERS & SETTERS
}
Any help is appreciated!

What is the SOQL to get all Public Calendars, in a Salesforce instance?

Does anyone know how to perform a query to get all public calendars? You can see the list by going to Setup ... Customize ... Activities .. Public Calendars and Resources
What are these calendar objects?
My goal is to find a way to show these calendars in a VisualForce page to make it easier for users to find them.
If you run a .getSobjectType() on the ID it comes up as a calendar object. When you try and query that object it says it's not available. It looks like the custom setting is the only route for now.
As near as I can tell, Salesforce hasn't directly exposed the Public Calendar object for customers to query directly.
Public Calendars seem to fall into the 023 namespace, which is a standard object, but I can't find any object in the Schema that have that namespace, which leads me to believe that SFDC has hidden them from us.
If you want to show the list in Visualforce, you could use a workaround using the PageReference GetContent() method on the Calendar page and then fetch the details from the html.
Note that this won't work in APEX triggers..
Public Class CalendarResource{
public Id crId {get;set;}
public String label {get;set;}
public String type {get;set;}
}
Pagereference r = new PageReference('/_ui/common/data/LookupResultsFrame?lkfm=swt&lknm=cal&lktp=023&cltp=resource&lksrch=#');
String html = r.getContent().toString();
List<CalendarResource> cals = new List<CalendarResource>();
Matcher m = Pattern.compile('lookupPick\\(\'swt\',\'cal_lkid\',\'cal\',\'\',\'(.*?)\',\'(.*?)\',\'\',\'\'\\)">(.*?)</a></TH><td class=" dataCell ">(.*?)<\\/td><\\/tr>').matcher(html);
//While there are labels
while (m.find()) {
//system.debug(m.group(3));
//system.debug(m.group(4));
CalendarResource cr = new CalendarResource();
cr.crId = m.group(1);
cr.label = m.group(2);
cr.type = m.group(4);
cals.add(cr);
}
for(CalendarResource cr : cals){
system.debug(cr.crId+'__'+cr.label+'___'+cr.type);
}
You can do this in the current API version by: "SELECT Id,Name FROM Calendar where Type='Resource'

Alternative to Using an Entity as a Parameter to an Invoke Method in WCF RIA Services

Howdy, ya'll! First question on StackOverflow! :-)
So here's the scenario: We're working on a web app with Silverlight 4 and using WCF RIA Services 1.0 SP1 Beta for the web service. I have my entities in the Entity Framework Designer, but I'm using a slightly-modified ADO.NET C# POCO Entity Generator template to generate the classes.
What I'd like to do is have a method inside a Domain Service with the following signature:
[EnableClientAccess]
public class ResultService : DomainService
{
[Invoke]
public SerializableResult CalculateResult(EntityOne e1, EntityTwo e2);
}
I am returning both EntityOne and EntityTwo to the client through queries in other services, like so:
[EnableClientAccess]
public class EntityOneService : DomainService
{
public IQueryable<EntityOne> GetEntityOnes();
}
[EnableClientAccess]
public class EntityOneService : DomainService
{
public IQueryable<EntityTwo> GetEntityTwos();
}
Those classes are successfully being generated in the Silverlight project. The SerializableResult does not have a key.
When I try to compile, I get the following error: "Operation named 'CalculateResult' does not conform to the required signature. Parameter types must be an entity or complex type, a collection of complex types, or one of the predefined serializable types."
In my research, the most helpful information I found were in the comments of this post by Jeff Handley.
Of note, Peter asked in a comment:
I get an 'does not conform to the required signature ...' compile error if my complex object has an [Key] Attribute. When I remove this attribute I can use the object as parameter for an Invoke operation.
Jeff's response:
This is by design. Complex objects cannot have Key properties. If you have a Key the class gets treated as an Entity.
So it sounds as if any further efforts to try to get my method to work will be futile. However, I was wondering if anyone else has come across this problem, and what they did to solve it.
Thanks very much!
I have the following and it works for me.
namespace BusinessApplication2.Web
{
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
[EnableClientAccess()]
public class DomainService1 : DomainService
{
public IQueryable<EntityOne> GetEntityOnes()
{
return null;
}
public IQueryable<EntityTwo> GetEntityTwos()
{
return null;
}
[Invoke]
public SerializableResult GetSerializableResult(EntityOne one, EntityTwo two)
{
return new SerializableResult() { Result = "It woooooorrrked!" };
}
}
public class EntityOne
{
[Key]
public int Id { get; set; }
}
public class EntityTwo
{
[Key]
public int Id { get; set; }
}
public class SerializableResult
{
public string Result { get; set; }
}
}
Many thanks to Mr. Jeff Handley and Mr. Dinesh Kulkarni for the answer (through Twitter).
In order for an Entity to be used as a parameter in an invoke method, that Entity must be exposed through a query method existing within the same DomainService. The intention for this restriction is that
"Each domain service needs to be able to stand on its own."
By adding two dummy Query methods (see Jeff's answer for an example), I was able to compile my code.

Resources