How to query by date using mongo repository in spring boot? - mongodb

I have developed an application in spring boot with mongo reposotory. I am using spring data jpa. And I declared in many tables createdDate as Date util package in java and date stores in the db as ISO formatted. When I query using mongo repository findByCreatedDate(Date date) which gives no result.
Below is my model class
#Document
public class BarModel extends BaseEntity {
#NotNull
#Size(min = 2, max = 140)
String name;
String address;
String city;
String state;
String zipcode;
String phone;
String description;
String primImage;
#DBRef
Location location;
#DBRef
List<Special> specials;
}
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
#Id
private String id;
#CreatedBy
private String createdBy = getCurrentAuditor();
#CreatedDate
#DateTimeFormat(iso = ISO.DATE_TIME)
private Date creationTime = new Date();
#CreatedBy
#LastModifiedBy
private String modifiedBy = getCurrentAuditor();
#CreatedDate
#LastModifiedDate
#DateTimeFormat(iso = ISO.DATE_TIME)
private Date modificationTime = new Date();
}
#Transactional
public interface BarModelRepository extends MongoRepository<BarModel, String> {
Page<BarModel> findByCreationTime(Pageable pageable, Date creationtime);
public List<BarModel> findByCreationTime(Date from, Date to);
}

Related

How to use date_format when using JPQL/JPA to do the sum group by month from column date

I have to get the total price in month from a date(LocalDate) yy-mm-dd with jpql query but i can't do it
with jpql with function : function('date_format',p.date,'%Y-%m')
//in the table of entity i have:
public class Reservation {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private double price;
#ManyToOne #JoinColumn(name="userId" )
public User user;
private LocalDate date;
private boolean confirmed;}
the class where i will put the result
public class MonthIncomes {
private LocalDate date ;
private double price;
public MonthIncomes (LocalDate date,double price){
this. date= date;
this.price = price;
}
//what i do in repository
public interface ReservationRepo extends JpaRepository<Reservation, Long> {
#Query(value = "select new com.food.dto.MonthIncomes( function('date_format',date,'%Y-%m'),SUM(p.price)) from Reservation p group by function('date_format',p.date,'%Y-%m')" )
public List<MonthIncomes> getIncomeByMonth();}`

Spring MongoDB: Auditing one-to-many relation subdocument

I am currently working on a self-taught project, thus I am a beginner in MongoDB and I am struggling to audit a subdocument in an one-to-many relation. For some reason none of the new records inserted in this collection is being audited, although audit is working fine for all the other collections.
Below is the structure of the collections in my project:
User document is the main Document - auditing ok
Provider is an embedded subdocument in User (One-to-One) - auditing ok
Address is an embedded set of documents in Provider (One-to-Many) auditing fail
public class User extends Audit<String>{
#Id
private String id;
private String email;
private String firstName;
private String lastName;
private String salt;
private String password;
private String role;
private Boolean isVerified;
private String userTempCode;
private LocalDateTime deactivationDate;
private Provider provider; // This subdocument gets audited no problem
...
public class Provider extends Audit<ObjectId>{
private ObjectId id = new ObjectId();
private LocalDate dob;
private String phone;
private Double price;
private Object geoLocation;
private Set<WeekDays> days;
private Set<TimeRange> hours;
private Set<Address> addresses; // Here is where I am having trouble, the createdBy, createdDate and so on, are not working
private String userId;
private LocalDateTime deactivationDate;
private Set<Reviews> ratings;
....
public class Address extends Audit<ObjectId>{
#Id
private ObjectId id = new ObjectId();
private String street;
private String street2;
private String city;
private String province;
private String country;
private String postalCode;
...
//Below My Audit class inherited by all documents
#Data
public abstract class Audit<T> implements Persistable<T> {
#CreatedBy
private String createdBy;
#CreatedDate
private LocalDateTime createdDate;
#LastModifiedBy
private String lastModifiedBy;
#LastModifiedDate
private LocalDateTime lastModifiedDate;
#Version
public Integer version;
}
So, why is my Set< Address> not being audited whereas the other documents are ok, am I missing something here?
Thank you!

Unable to override Auditable fields - createdAt

I've access_tokens collection and here is the corresponding class:
public class AccessToken extends Auditable {
#Id
private String id;
#NotBlank
private String token;
#DBRef
#NotBlank
private User user;
#NotBlank
private String origin;
public void setOrigin(String origin) {
this.origin = JwtUtils.getOrigin(origin);
}
#Indexed(expireAfter = "1d")
private LocalDateTime createdAt;
}
And here is the Auditable class:
public class Auditable {
#CreatedDate
private LocalDateTime createdAt;
#LastModifiedDate
private LocalDateTime updatedAt;
#CreatedBy
private ObjectId createdBy;
#LastModifiedBy
private ObjectId updatedBy;
}
The reason I'm defining createdAt in AccessToken is, I want to create a TTL index (basically I want to delete all access tokens after one day). But I'm getting following error:
Caused by: org.springframework.data.mapping.MappingException: Ambiguous field mapping detected! Both #org.springframework.data.annotation.CreatedDate()private java.time.LocalDateTime com.iof.models.Auditable.createdAt and private java.time.LocalDateTime com.iof.models.AccessToken.createdAt map to the same field name createdAt! Disambiguate using #Field annotation!
How can I solve this?

How to build nested object using criteriaBuilder.construct in JPA Criteria Query

I want to query the list of the phone with the person as a phone DTO object but while I construct a DTO object it provides an error.
Phone Entity:
public class Phone {
#Id
#GeneratedValue
private Long id;
private String number;
#Enumerated(EnumType.STRING)
private PhoneType type;
#ManyToOne
#JoinColumn(name = "person_id")
private Person person;
}
Person Entity:
public class Person {
#Id
#GeneratedValue
private long id;
private String name;
private String nickName;
private String address;
private LocalDateTime createdAt;
#Version
private int version;
#OneToMany(mappedBy = "person" cascade = CascadeType.ALL)
private List<Phone> phones;
}
Phone DTO:
public class PhoneDTO {
private Long id;
private String number;
private PhoneType type;
private PersonDTO person;
}
Person DTO:
public class PersonDTO {
private long id;
private String name;
private String nickName;
private String address;
private LocalDateTime createdAt;
private int version;
}
Criteria query:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<PhoneDTO> criteriaQuery = builder.createQuery(PhoneDTO.class);
Root<Phone> root = criteriaQuery.from(Phone.class);
Join<Phone, Person> person = root.join("person");
Path<Object> id = root.get("id");
Path<Object> number = root.get("number");
Path<Object> type = root.get("type");
Path<Object> personId = person.get("id");
Path<Object> name = person.get("name");
Path<Object> nickName = person.get("nickName");
Path<Object> address = person.get("address");
Path<Object> createdAt = person.get("createdAt");
Path<Object> version = person.get("version");
criteriaQuery.select(builder.construct(PhoneDTO.class, id, number, type, builder.construct(PersonDTO.class, personId, name, nickName, address, createdAt, version)));
TypedQuery<PhoneDTO> query = em.createQuery(criteriaQuery);
How to do this??
criteriaQuery.select(builder.construct(PhoneDTO.class, id, number, type, builder.construct(PersonMediumDTO.class, personId, name, nickName, address, createdAt, version)));
How to construct a nested object??

Spring data MongoDB match, lookup and projection to select only required field from looked-up document

I have below two Document structures. In the structure CRMContact.orgGroupId == OrganizationGroup.id. I would like to fetch all the CRMContact document that matches with sharedGroupIds and also select only a few fields from CRMContact and only OrganizationGroup.groupownername from OrganizationGroup and match/populate groupId (with only one field [groupownername] populated). I have used below custom implementation but didn't work.
I have included aggregarionsNotWorking which is not working and aggregarions returning entire OrganizationGroup populated. How to achieve this i.e. just to populate groupownername field, using spring data mongodb?
#Document(collection = "ww_crm_contact")
public class CRMContact{
#Id
protected String id;
private String displayName;
private String firstName;
private String middleName;
private String lastName;
private OrganizationGroup groupId; //Ignore //Modified field name orgGroupId
#Indexed(name = "CRMCONTACT_SHAREDGROUPID_IDX",background = true)
private List<String> sharedGroupIds = new LinkedList<>();
#Indexed(name = "CRMCONTACT_ORGGROUPID_IDX",background = true)
private String orgGroupId;
}
#Document(collection = "ww_organization_groups")
public class OrganizationGroup {
private static final long serialVersionUID = 600049975643062552L;
#Id
protected String id;
private String groupName;
private int riaId;
private Boolean isPrivate;
private String description;
private Boolean deleted;
#Transient
private int count;
private String groupownerid;
private String groupownername;
}
#Repository
public class CustomCRMContactDAO {
#Autowired
MongoTemplate mongoTemplate;
public List<CRMContact> getContactsPresentInGroup(List<ObjectId> objectIds){
LookupOperation lookupOperation = LookupOperation.newLookup().from("ww_organization_groups").localField("orgGroupId").foreignField("_id").as("groupId");
ProjectionOperation fields = project("firstName","lastName", "primaryId","displayName","groupId.groupownername");
Aggregation aggregarionsNotWorking = Aggregation.newAggregation(Aggregation.match(Criteria.where("sharedGroupIds").in(objectIds)),lookupOperation,unwind("groupId"),fields); //Not Working even if I change the field only to groupownername
Aggregation aggregarions = Aggregation.newAggregation(Aggregation.match(Criteria.where("sharedGroupIds").in(objectIds)),lookupOperation,fields); //
List<CRMContact> crmContacts = mongoTemplate.aggregate(aggregarions, "ww_crm_contact",CRMContact.class).getMappedResults();
return crmContacts;
}
}