Groovy : fetching values of nested objects using xpath kind - xpath

I have POJO with nested objects which i need to translate to a simple object with out nesting
for example i have a Person and Address as below
public class Person {
private String firstName;
private String lastName;
private Address address;
}
public class Address {
private String lineOne;
private String lineTwo;
}
I need to translate Person to PersonFlat which looks like
public class PersonFlat {
private String firstName;
private String lastName;
private String Address_lineOne;
private String Address_lineTwo;
}
is there any way where i can do xpath kind of extraction on the Person instance to get the Address.lineOne and Address.lineTwo using groovy metaClass ?

Related

Spring MongoDB Query Criteria by keys of Map

I have document
public class Person {
private String id;
private String email;
private String firstName;
private String lastName;
private Map<String, Boolean> hobbies;
}
And have request with Set of reqHobbies. I need to find persons from my collection with hobbies of set.
I find a solution like
query.addCriteria(Criteria.where("hobbies").all(reqHobbies)); - this work, if my hobbies is List/Set.
Thanks for the help!

CQEngine Query nested object using parser.retrieve

I have a nested object like
public class SQSMessage implements Serializable {
private String type;
private boolean isEntity;
private String eventType;
private SystemInfo systemInfo;
private DomainAttributes domainAttributes;
#Data
public static class SystemInfo implements Serializable {
private String identifier;
private String ownedBy;
private Payload payload;
private EntityTags entityTags;
private long createdOn;
private String createdBy;
private long version;
private long lastUpdatedOn;
private String lastUpdatedBy;
private String attrEncKeyName;
#Data
public static class Payload implements Serializable {
private String bucketName;
private String objName;
private String encKeyName;
private byte[] payloadBytes;
private byte[] decryptedBytes;
private byte[] sanitizedBytes;
}
#Data
public static class EntityTags implements Serializable {
private List<Tag> tags;
#Data
public static class Tag implements Serializable {
private String tagName;
private String tagValue;
}
}
}
#Data
public static class DomainAttributes implements Serializable {
private String updatedByAuthId;
private String saveType;
private String docName;
private String ceDataType;
private String year;
private String appId;
private String formSetId;
private String appSku;
private String deviceId;
private String deviceName;
}
}
I would like to query the collection of SQSObjects by applying a filter like
ResultSet<SQSMessage> results = parser.retrieve(indexedSQSMessage, "SELECT * FROM indexedSQSMessage WHERE type='income' and DomainAttributes.saveType in ('endSession', 'cancelled')or (DomainAttributes.countryCode is null or DomainAttributes.countryCode='US'");
Is that possible using CQEngine? if yes.. please send me the examples.
The reason why I want o make that as sql... where clause is dynamic for various use cases.
Your example is more complicated than it needs to be for the question, so I am just skimming it. (Read about SSCCE)
However generally this kind of thing should be possible. See this related question/answer for how to construct nested queries: Can CQEngine query an object inside another object
If you set up attributes like that, you should be able to use them in SQL queries as well as programmatically.

extract less number of columns from database table as defined in #Entity class and map to same entity pojo in spring boot

My #Entity class is
#Entity
class Demo{
#Id
private int id;
private int firstName;
private String lastName;
private String address;
}
And the #Repositiory Interface is having method as below
#Query(value="select d.id,d.firstName from demo d",nativeQuery=true)
List<Demo> fetchDetails();
Here exception is thrown as : The field "lastName" is not present in ResultSet
Do i need to create another pojo that contain id,firstName as variable and change fetchDetails() methods to as below:
#Query(value="select d.id,d.firstName from demo d",nativeQuery=true)
List<New Pojo class with only 2 fields that is to be selected> fetchDetails();
i want the partially selected resultset to get mapped to Entity Demo automatically.
I their any way to map these two columns to the Entity Demo
You can use Class-Based Projections that you can have a lot of constructor you need according to all fields you want to fetch
For example, here's a projection class for the Demo entity:
public class DemoDto {
private int id;
private int firstName;
private String lastName;
private String address;
// getters, equals and hashCode
}
public DemoDto(String firstName) {
this.firstName = firstName;
}
public DemoDto(int id, String firstName) {
this.id = id;
this.firstName = firstName;
}
public DemoDto(int id, String firstName, String address) {
this.id = id;
this.firstName = firstName;
this.address = address;
}
You must also define equals and hashCode implementations – they allow Spring Data to process projection objects in a collection.
In your repository you can add some query with JPQL Constructor like:
#Query(value="select new your.class.fullname.package.DemoDto(d.firstName) from Demo d")
List<DemoDto> fetchNameOnly();
#Query(value="select new your.class.fullname.package.DemoDto(d.id, d.firstName) from Demo d")
List<DemoDto> fetchIdAndNameOnly();
#Query(value="select new your.class.fullname.package.DemoDto(d.id, d.firstName, d.address) from Demo d")
List<DemoDto> fetchAllDetails();
Projections are introduced for that exact reason. Have a look at the documentation here
What you need is this, create an interface like this with the getter method for the fields you want in the result.
interface IdAndNameOnly {
String getFirstname();
int getId();
}
Modify the query like this. You do not need #Query for simple queries like the one you have.
List<IdAndNameOnly> findAll();
You can convert object of type IdAndNameOnly to your Entity type. But that doesn't make much sense. You can just get the fields which you need from the IdAndNameOnly object. If not what is the point of fetching fewer fields.
If I'm not mistaken you need to create a custom constructor and use it JPQL Constructor Expressions.
Something like this would do the job:
#Entity
class Demo{
#Id
private int id;
private int firstName;
private String lastName;
private String address;
public Demo() {
// JPA needs the default constructor
}
public Demo(int id, String firstName) {
this.id = id;
this.firstName = firstName;
}
}
And the usage something like this:
#Query(value="select new your.class.fullname.package.Demo(d.id,d.firstName) from Demo d")
List<Demo> fetchDetails();

How do I map polymorphic Java classes to MongoDB entities using Spring?

I am relatively new to Spring. I'm trying to implement a simple CRUD RESTful API for MongoDB. I'm having issues with mapping annotations when it comes to polymorphic classes.
Here's my Employee class that holds a list of Allocations. The idea is that an employee can have multiple allocations at once. An Allocation could either be a training or a department.
public class Employee {
#Id
private String id;
private String empCode;
private String firstName;
private String lastName;
private List<Allocation> allocations;
// Getters, setters and Constructor
}
Here's the Allocation class.
public class Allocation {
#Id
private String id;
private LocalDate startDate;
private LocalDate endDate;
private String location;
}
And here are the Department and Training classes.
public class Training extends Allocation {
#Id
private String id;
private String courseName;
}
public class Department extends Allocation {
#Id
private String id;
private String deptName;
}
How do I map the above classes using Spring annotations? When I retrieve an Employee, I want the JSON to have an array of Allocations that include both Training Programs and Departments.

Nested Mapping in Mapstruct

I am new to MapStruct API, can anyone say how to do nested Mapping.
I have two classes one is my actual purchaseOrder class, which is known my target class, the other is EDPurchaseOrder class which known as source file, here don't worry about the naming conventions I used, just go with source and target files.
Source Classes
Source class EDCustomerOrder and its reference classes
public class EDCustomerOrder{
private Integer orderID;
private String orderNumber;
private BigDecimal orderTotalQty;
private String UOM;
private PickupDTO pickupPoints;
private Integer supplierID;
private String supplierName;
private String supplierNature;
private EDAddress supplierEDAddress;
}
public class EDPickup{
private List<EDPOItem> items;
}
public class EDAddress{
private String addressLine1;
private String addressLine2;
private String addressLine3;
private String city;
private String state;
private string countryCode;
private String country;
private String postalCode;
}
public class EDPOItem{
private Integer itemID;
private String itemCode;
private String itemDescription;
private Integer itemQuantity;
}
Target classes
Here my target class CustomerOrder and its reference classes
public class CustomerOrder{
private Integer orderID;
private String orderNumber;
private List<Pickup> pickupPoints;
private Supplier supplierDetail;
}
public class Pickup{
private Integer pickupID;
private Integer pickupLocationNumber;
private List<POItem> items;
}
public class POItem{
private Integer itemID;
private String itemCode;
private String itemDescription;
private Integer itemQuantity;
}
public class Supplier{
private Integer supplierID;
private String supplierName;
private String supplierNature;
private Address supplierAddress;
}
public class Address{
private String addressLine1;
private String addressLine2;
private String addressLine3;
private String city;
private String state;
private string countryCode;
private String country;
private String postalCode;
}
So I suppose you have the same hierarchy of objects on the target side, e.g. a SongDTO, LibraryDTO and TrackDTO.
Then you'd have to declare a mapping method for each of those pairs of corresponding objects, configuring it via #Mapping as needed:
public interface MyMapper {
#Mapping(source="name", target="title")
SongDTO songToDto(Song song);
LibraryDTO libraryToDto(Library library);
TrackDTO trackToDto(Track track);
}
Then e.g. the generated implementation of songToDto() will invoke libraryToDto() in order to map the song's library into the song DTO's library DTO.
Also check out the reference guide to learn more.
#Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CandidateProfessionalEntityAndDTOMapper {
#Mappings({
#Mapping(source = "company.companyId", target = "companyId"),
})
Clazz1
entityToReferencesMapping(Clazz2 entity);
}
public class Clazz2 {
private String companyName;
private Company company;
}
public class Company{
Integer companyId;
}
public class Clazz1 {
private String companyId;
private String companyName;
}

Resources