I'm trying to retrieve a list of products by one of their variants ids but I simply couldn't figure it out with nested classes and a list.
I've tried the method
List<Product> findAllByFooProductVariantsCodeIn(List<String> variantCodes);
It didn't work out as well.
public class Product extends DatabaseEntity {
private FooProduct fooProduct;
}
public class FooProduct {
private String title;
private String vendor;
private String productType;
private String tags;
private List<FooProductVariant> variants;
}
public class FooProductVariant {
private String productId;
private String title;
private String price;
private String variantCode;
}
An example of this could be 3 base Products with 3 variants
1st product ABC
2nd product RTY
3rd product XYZ
and the variantCodes of these products:
ABC-003,
RTY-001,
XYZ-002
the parameter variantCodes does contain all these variant codes and the method is expected to return 3 products as ABC, RTY, XYZ. Query needs to get into the nested FooProduct and after the FooProductVariant list inside it, and unnest the variant codes and find the Product from one of these variant Codes
Is this doable with Spring Data JPA?
Related
Folks..!!
Have a requirement to work on reading specific column data by using Spring batch. Well i am creating a spring batch application which has a requirement to read specific column.
In my csv file i have a column "msisdn", that field is mapped to an POJO. I want to read the values of "msisdn" no which is of Long data type.
well i am taking reference of below link.
read only selective columns from csv file using spring batch
Customer POJO
public class Customer {
private String id_type;
private String id_number;
private String customer_name;
private String email_address;
private LocalDate birthday;
private String citizenship;
private String address;
private Long msisdn;
private LocalDateTime kyc_date;
private String kyc_level;
private String goalscore;
private String mobile_network;
}
I am using a CustomMapper class to implement this feature. As you can see CustomMapper class implements FieldSetMapper type. fieldSet method returns String[] Array and msisdn is of Long type.Not able to understand how to get all values in msisdn column as fieldSet is only giving String[] type of data.
CustomMapper
============
public class CustomMapper implements FieldSetMapper<Customer> {
#Override
public Customer mapFieldSet(FieldSet fieldSet) throws BindException {
String[] custArray = null;
Customer customer = new Customer();
customer.setMsisdn(fieldSet.get);
return null;
}
}
please help me on this?
You can use fieldSet.readLong(int index) or fieldSet.readLong(String name) to select a field by name or index from the field set. Obviously this field should have been selected when parsing the file in your item reader.
I am trying to query based on Object attributes combination in MongoDB:
My Object looks like:
#Getter
#Setter
class Person {
private String name;
private String email;
private Address address;
}
Address entity looks like:
#Getter
#Setter
class Address {
private String city;
private String state;
private String postal;
private String country;
}
Assume that above classes are also annotated with necessary attributes required for MongoDB collections.
Now when I am about to query from a PersonRepo interface that extends MongoRepository, as:
public interface PersonRepo extends MongoRepository<Person, String> {
}
The objective is to fetch all result-set where Address matches any combination of city, state, postal or country. For example, I want to fetch all results where city=XYZCity, state = ABCState, Postal might not be provided and country might be DEFCountry.
Address can be in any combination and whatever combination matches, the result-set could be produced.
I am using java+Spring framework+Hibernate for creating rest api but I have stumbled upon retrieving details of a table using foreign key attributes.
I have the following tables::
https://i.stack.imgur.com/lG7UR.png
I am retrieving all the ratings given using product id and then mapping to DTO, now I also want to populate the username using idusers as this is my foreign key.
Same is the case when I try to retrieve ratings given by the users, instead of displaying idproducts I want to display the product name and product description as It is a foreign key.
Any advice on how to do so using DTO's.
This is a perfect use case for Blaze-Persistence Entity Views.
Blaze-Persistence is a query builder on top of JPA which supports many of the advanced DBMS features on top of the JPA model. I created Entity Views on top of it to allow easy mapping between JPA models and custom interface defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.
Assuming you have an entity model like this
#Entity
public class User {
#Id
Integer id;
String role;
String username;
String password;
boolean enabled;
}
#Entity
public class Product {
#Id
Integer id;
String imageUrl;
String category;
int productPrice;
int productQuantity;
String productName;
String productDesc;
#OneToMany(mappedBy = "product")
Set<Rating> ratings;
}
#Entity
public class Rating {
#Id
Integer id;
int rating;
String review;
String ratingscol;
#ManyToOne(fetch = LAZY)
Product product;
#ManyToOne(fetch = LAZY)
User user;
}
A DTO mapping for your model could look as simple as the following
#EntityView(Rating.class)
interface RatingDto {
Integer getId();
UserDto getUser();
ProductDto getProduct();
}
#EntityView(User.class)
interface UserDto {
Integer getId();
String getUsername();
}
#EntityView(Rating.class)
interface ProductDto {
Integer getId();
String getProductName();
String getProductDesc();
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
RatingDto dto = entityViewManager.find(entityManager, RatingDto.class, id);
But the Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
It will only fetch the mappings that you tell it to fetch
You can use ModelMapper when converting a DTO to an Entity bean and back from Entity bean to a DTO.
Add ModelMapper to your project
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.5</version>
</dependency>
Define the ModelMapper bean in your Spring configuration
#Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
Assuming the following models based on the given ER diagram you have given
public class UserDto {
Integer userId;
String role;
String username;
String password;
boolean enabled;
...default and parameterized constructor
...getter and setter methods
}
public class ProductDto {
Integer productId;
String imageUrl;
String category;
int productPrice;
int productQuantity;
String productName;
String productDesc;
...default and parameterized constructor
...getter and setter methods
}
public class RatingDto {
#Id
Integer id;
int rating;
String review;
String ratingscol;
ProductDto productDto;
UserDto userDto;
...default and parameterized constructor
...getter and setter methods
}
You can retrieve the ratings of a product using product id along with the user details by using the following method
#Repository
public interface RatingRepository extends JpaRepository<Rating, Integer>{
List<Rating> findByProduct_ProductId(Integer productId);
}
Then mapping rating objects to DTO
RatingDto ratingDto = modelMapper.map(rating, RatingDto.class);
Now you can retrieve username as following
ratingsDto.getUserDto().getUserName()
The same way you can retrieve the ratings by userId and access product details
In spring data JPA we can write query methods to execute query. I have two entities
class A {
#Id
#Column
private String id;
private String name;
#ManyToOne
#JoinColumn(name = "b_field")
private B b;
}
class B {
#Id
#KeyField
#Column
private String id;
private String b_field
}
I want to write a query method "findByNameOrderByb_field" i.e find all the rows having name as provided and order the results on the basis of class B's field i.e b_field. Writing above function is not returning ordered results. Is there any way I can write this orderby query method in spring boot.
public interface ARepository extends CrudRepository<A, String> {
List<A> findByNameOrderByb_field(String name);
}
the above function is not returning ordered results based on B's b_field.
To access properties of B you have to include the field name of B in the declaration of the query method.
public interface ARepository extends CrudRepository<A, String> {
List<A> findByNameOrderByb_b_field(String name);
}
More information how SpringData resolves nested Properties can be found under:
Query Property Expressions
My POJO Datasource basically contains following structure.
// Company.java
public class Company implements Serializable {
private static final long serialVersionUID = 3130918429913376956L;
private String name;
private String address;
private String contactPerson;
private String mobile;
private String fax;
private String bankDetails;
private String email;
private List<Employee> emps;
//getter and setter.
}
// Employee.java
public class Employee implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4473328670062370497L;
private String name;
private int age;
private String designation;
//getter and setter
}
My scenario is like following
One PDF report may have more that one Company (ie List< Company >)
In case of more than one Company, it should start at new page.
If Employee list goes to next page then it should repeat Header on the next page.
Layout -
Layout xml source
Output Page 1
Page 2
There are two issues with this design
Employee Name header is getting repeated for every employee.
Company Header (Comp Name -> Company A ) should be rendered only once.
Can anyone suggest me correct approach ? Thanks in advance.
Move the 'company name' to the Header row and set the header property to not repeating on new pages. Move the 'Employee name' out of the grouping with 'Employee', so up to the level where 'company name' is now.
I think you know everything to solve this, you just have to fiddle with the groupings a bit.