How can I get a list of object and then convert them to a page? - java

I have a Product class
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Data
public class Product extends AbsEntity {
#Column(nullable = false, unique = true)
private String name;
#Length(max = 500)
#Column(nullable = false)
private String description;
private double price;//Evaluated in the $
#OneToOne
private Category category;
#OnDelete(action = OnDeleteAction.CASCADE)
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private User owner;
#OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
private Attachment attachment;
}
and repository:
#Repository
public interface ProductRepository extends JpaRepository<Product, UUID> {
boolean existsByNameAndOwner(String name, User owner);
List<Product> findAllByCategoryName(String categoryName);
List<Product> findAllByOwnerId(UUID owner_id);
}
When I try to get them and then page:
public HttpEntity<?> getProducts(int pageNum, int pageSize) {
Pageable pageable = PageRequest.of(pageNum, pageSize);
List<ProductDto> productDtoList =
productRepository.findAll().stream().map(helperClass::mapProductToProductDto).
collect(Collectors.toList());
Page<ProductDto> products = new PageImpl<>(productDtoList, pageable, productDtoList.size());
return ResponseEntity.ok(products);
}
and my helperClass method :
public ProductDto mapProductToProductDto(Product product) {
ProductDto productDto = new ProductDto();
productDto.setName(product.getName());
productDto.setPicture(product.getAttachment().getContent());
productDto.setPrice(product.getPrice());
productDto.setDescription(product.getDescription());
productDto.setOwnerName(product.getOwner().getFullName());
productDto.setCategoryName(product.getCategory().getName());
productDto.setAddedDate(product.getCreatedAt());
return productDto;
}
It is not returning necessary page but returning me all products in a single page. Is there a way to receive a list of object and then turn them ito a page?? What is a problem here?

Pass the Pageable to findAll:
Page<Product> page = productRepository.findAll(pageable);
List<ProductDto> productList = page.getContent().stream()
.map(helperClass::mapProductToProductDto).collect(Collectors.toList());

To return a Pageable way, you can modify your findAll method as this
Page productPage = productRepository.findAll(pageable);
you can modify the code as follows:
public HttpEntity<?> getProducts(int pageNum, int pageSize) {
Pageable pageable = PageRequest.of(pageNum, pageSize);
Page<Product> productPage = productRepository.findAll(pageable);
List<ProductDto> productDtoList = productPage.getContent().stream()
.map(helperClass::mapProductToProductDto)
.collect(Collectors.toList());
Page<ProductDto> productDtoPage = new PageImpl<>(productDtoList, pageable, productPage.getTotalElements());
return ResponseEntity.ok(productDtoPage);
}

Related

Spring Boot - SQL error instead of thrown exception

I'm making my first Spring Boot project, and it's working well. It uses a H2 database. The problem is that it returns 5xx HTTP responses, instead of 4xx with exceptions in cases of sql errors.
For example, I have this constraint:
Pet.java
#Table(uniqueConstraints={
#UniqueConstraint(columnNames = {"name","customer_id"})
})
I made this constraint because you shouldn't be able to save 2 pets with the same name, for the same owner (customer).
But when I try to POST a pet with the same name, for the same owner, it returns me an 5xx error, and SQL error appear in the log.
Pet.java
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
#Entity(name = "pet")
#Table(uniqueConstraints={
#UniqueConstraint(columnNames = {"name","customer_id"})
})
public class Pet implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Getter
#Setter
#Column(nullable = false, insertable = false, updatable = false)
private Long id;
#Column (name = "name", nullable = false)
private String name;
#Column (name = "birthdate")
private LocalDate birthdate;
#Column (name = "weight_KG")
private Double weight_KG;
#Column
private String color;
#Column
String breed;
#Getter
#Setter
#ManyToOne (cascade = CascadeType.ALL)
#JoinColumn (name = "customer_id", referencedColumnName = "id", nullable = false)
private Customer customer;
#JsonIgnore
#OneToMany(mappedBy = "pet")
List<Vaccination> vaccination;
}
Customer.java
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
#Entity (name = "customer")
public class Customer implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Getter
#Setter
#Column(nullable = false, insertable = false, updatable = false)
private Long id;
#Column (name = "name", nullable = false, unique = true)
private String name;
#Column (name = "surname")
private String surname;
#Column (name = "birthdate")
private LocalDate birthdate;
#OneToMany(mappedBy = "customer",cascade={CascadeType.ALL})
#JsonIgnore
private List<Pet> pets;
}
CustomerController.java
#RestController
#RequestMapping("/customer")
public class CustomerController {
#Autowired
private CustomerService customerService;
#Autowired
private ModelMapper modelMapper;
#Autowired
private CustomerRepository customerRepository;
#PostMapping
#ResponseStatus(HttpStatus.CREATED)
public Customer save(#RequestBody Customer customer) {
if (customerRepository.findByName(customer.getName()).isPresent()){
throw new ResponseStatusException(HttpStatus.CONFLICT, "Customer with the inserted name already exists.");
}
//customerRepository.findByName(customer.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found"));
return customerService.save(customer);
}
#GetMapping
#ResponseStatus(HttpStatus.OK)
public List<Customer> findAllCustomers(){
return customerService.findAll();
}
#GetMapping("/{id}")
#ResponseStatus(HttpStatus.OK)
public Customer findCustomerById(#PathVariable("id") Long id) {
return customerService.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found"));
}
#GetMapping("/name/{name}")
#ResponseStatus(HttpStatus.OK)
public List<Customer> findCustomerByName(#PathVariable("name") String name) {
List<Customer> customer = customerRepository.findByNameStartsWithIgnoreCase(name);
return customer;
}
#DeleteMapping("/{id}")
#ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCustomer(#PathVariable("id") Long id){
customerService.findById(id)
.map(customer -> {
customerService.deleteById(customer.getId());
return Void.TYPE;
}).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found"));
}
#PutMapping("/{id}")
#ResponseStatus(HttpStatus.NO_CONTENT)
public void updateCustomer (#PathVariable("id") Long id, #RequestBody Customer customer) {
customerService.findById(id)
.map(customerBase -> {
modelMapper.map(customer,customerBase);
customerService.save(customerBase);
return Void.TYPE;
}).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer not found"));
}
}
PetController.java
#RestController
#RequestMapping("/pet")
public class PetController {
#Autowired
private PetService petService;
#Autowired
private ModelMapper modelMapper;
#Autowired
private CustomerRepository customerRepository;
#Autowired
private PetRepository petRepository;
#PostMapping
#ResponseStatus(HttpStatus.CREATED)
public Pet save(#RequestBody Pet pet){
customerRepository.findById(pet.getCustomer().getId()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Customer does not exists."));
Customer customer = customerRepository.findById(pet.getCustomer().getId()).get();
pet.setCustomer(customer);
//petRepository.findByCustomer(customer);
return petService.save(pet);
}
#GetMapping
#ResponseStatus(HttpStatus.OK)
public List<Pet> findAllPets(){
return petService.findAll();
}
#GetMapping("/{id}")
#ResponseStatus(HttpStatus.OK)
public Pet findPetById(#PathVariable("id") Long id){
return petService.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Pet not found"));
}
#GetMapping("/name/{name}")
#ResponseStatus(HttpStatus.OK)
public List<Pet> findPetByName(#PathVariable("name") String name){
List<Pet> pet = petRepository.findByNameStartsWithIgnoreCase(name);
return pet;
}
#DeleteMapping("/{id}")
#ResponseStatus(HttpStatus.NO_CONTENT)
public void deletePet(#PathVariable("id") Long id){
petService.findById(id)
.map(pet -> {
petService.deleteById(pet.getId());
return Void.TYPE;
}).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Pet not found"));
}
#PutMapping("/{id}")
#ResponseStatus(HttpStatus.NO_CONTENT)
public void updatePet (#PathVariable("id") Long id, #RequestBody Pet pet) {
petService.findById(id)
.map(petBase -> {
modelMapper.map(pet,petBase);
petService.save(petBase);
return Void.TYPE;
}).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Pet not found"));
}
}
I had the same problem when saving two customers with the same name, but I solved the problem by adding these lines of code to the controller:
CustomerController.java
if (customerRepository.findByName(customer.getName()).isPresent()){
throw new ResponseStatusException(HttpStatus.CONFLICT, "Customer with the inserted name already exists.");
}
But the pet's constraint is more complex, and I couldn't find a solution the same way I did above. I tried to create a petRepository.findbyCustomer, send the customer that was gonna be saved. Then I would have a list of pets that have the same customer, and somehow try to findByName these pets, searching for the name of the pet that is going to be saved.
But I stopped with these crazy idea, because there could be a cleaner way to to this. I tried to search for it, but couldn't find a solution.
What I want is a exception throw in the case I try to save two pets with the same name for the same owner. I don't want SQL errors, and I don't want 5xx returns.

Hibernate Criteria. Construct with inheritance

I have super class AuditEntity.
#Getter
#Setter
#MappedSuperclass
#EntityListeners(AuditEntityListener.class)
public abstract class AuditEntity {
public static final String ID = "id";
public static final String ORGANIZATION = "organization";
public static final String CREATED_BY = "createdBy";
public static final String MODIFIED_BY = "modifiedBy";
public static final String CREATED_DATETIME = "createdDatetime";
public static final String MODIFIED_DATETIME = "modifiedDatetime";
public static final String STATE = "state";
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "organization_id")
protected Organization organization;
#Column(name = "created_datetime")
protected Instant createdDatetime;
#Column(name = "modified_datetime")
protected Instant modifiedDatetime;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "created_by")
protected User createdBy;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "modified_by")
protected User modifiedBy;
#Enumerated(EnumType.STRING)
#Column(name = "state")
protected State state;
}
And entity extends the superclass.
#Getter
#Setter
#Builder
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode(of = {"id"}, callSuper = false)
#Entity
#Table(name = "inventory_request")
public class InventoryRequest extends AuditEntity {
public static final String NAME = "name";
public static final String REQUESTER = "requester";
public static final String SOURCE = "source";
public static final String EVENT = "event";
public static final String TRANSFER = "transfers";
public static final String ASSIGNMENT = "assignment";
public static final String INVENTORY_REQUEST_STATUS = "status";
public static final String NOTES = "notes";
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "inventory_request_id")
private UUID id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "email", nullable = false)
private String email;
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
#JoinColumn(name = "requester_id")
private User requester;
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
#JoinColumn(name = "source_id")
#ApiModelProperty(hidden = true)
private User source;
#Enumerated(EnumType.STRING)
#Column(name = "status", nullable = false, length = 24)
private InventoryRequestStatus status;
#Column(name = "carrier")
private String carrier;
#Column(name = "tracking_number")
private String trackingNumber;
#Column(name = "note", length = 1024)
private String note;
#JsonManagedReference
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
#JoinColumn(name = "event_id")
private Event event;
#Column(name = "number", nullable = false)
private Long number;
#Column(name = "tracking_enabled", nullable = false)
private Boolean trackingEnabled;
#JsonManagedReference
#OneToMany(fetch = FetchType.LAZY, mappedBy = Transfer.INVENTORY_REQUEST)
private Set<Transfer> transfers;
#JsonManagedReference
#OneToMany(fetch = FetchType.LAZY, mappedBy = InventoryRequestAssignment.INVENTORY_REQUEST)
private Set<InventoryRequestAssignment> assignment;
#JsonManagedReference
#OneToMany(fetch = FetchType.LAZY, mappedBy = InventoryRequestNote.INVENTORY_REQUEST)
private Set<InventoryRequestNote> notes;
}
This is a class i want to select with criteria api.
#NoArgsConstructor
#Getter
#Setter
public class InventoryRequestDTO extends InventoryRequest {
public InventoryRequestDTO(InventoryRequest inventoryRequest,
Long completeSetsQuantity,
Long specificProductQuantity) {
super(inventoryRequest.getId(),
inventoryRequest.getName(),
inventoryRequest.getEmail(),
inventoryRequest.getRequester(),
inventoryRequest.getSource(),
inventoryRequest.getStatus(),
inventoryRequest.getCarrier(),
inventoryRequest.getTrackingNumber(),
inventoryRequest.getNote(),
inventoryRequest.getEvent(),
inventoryRequest.getNumber(),
inventoryRequest.getTrackingEnabled(),
inventoryRequest.getTransfers(),
inventoryRequest.getAssignment(),
inventoryRequest.getNotes());
this.completeSetsQuantity = completeSetsQuantity;
this.specificProductQuantity = specificProductQuantity;
}
private Long completeSetsQuantity;
private Long specificProductQuantity;
}
And this is method i tried to do that.
#Transactional
public Page<? extends InventoryRequest> getInventoryRequestPage(InventoryRequestSearchParams searchParams, Pageable pageable) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<InventoryRequest> query = builder.createQuery(InventoryRequest.class);
Root<InventoryRequest> root = query.from(InventoryRequest.class);
Join<InventoryRequest, InventoryRequestAssignment> assignmentJoin = root.join(InventoryRequest.ASSIGNMENT, JoinType.LEFT);
Expression<Long> specificProductQuantity = builder.count(builder.selectCase()
.when(assignmentJoin.get(InventoryRequestAssignment.CATALOG).isNotNull(), 1)
.otherwise(0));
Expression<Long> completeSetsQuantity = builder.count(builder.selectCase()
.when(assignmentJoin.get(InventoryRequestAssignment.CATALOG).isNull(), 1)
.otherwise(0));
Predicate predicate = InventoryRequestSpecificationComposer.builder()
.searchParams(searchParams)
.build()
.compose()
.toPredicate(root, query, builder);
query.select(
builder.construct(InventoryRequestDTO.class,
root,
completeSetsQuantity,
specificProductQuantity))
.where(predicate);
Query q = entityManager.createQuery(query);
int totalRows = q.getResultList().size();
q.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());
q.setMaxResults(pageable.getPageSize());
return new PageImpl<>(q.getResultList(), pageable, totalRows);
}
But i get this exception.
org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=generatedAlias2,role=com.connectsx.core.model.entity.InventoryRequest.createdBy,tableName=users,tableAlias=user2_,origin=inventory_request inventoryr0_,columns={inventoryr0_.created_by ,className=com.connectsx.core.model.entity.User}}]
Also I've got specification builder for audit entity, which fetches organization, created_by, modified_by properties. But if i select InventoryRequest.class, it works fine, and with DTO it fails.
There is no point in using a constructor expression if you pass the whole entity. You could just as well fetch the entity and call the constructor on the result list objects. However, if you really want a performance improvement, this is a perfect use case for Blaze-Persistence Entity Views.
I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) 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.
A sample model for your use case could look like the following:
#EntityView(InventoryRequest.class)
public interface InventoryRequestDTO {
#IdMapping
UUID getId();
String getName();
String getEmail();
UserDTO getRequester();
UserDTO getSource();
InventoryRequestStatus getStatus();
String getCarrier();
String getTrackingNumber();
String getNote();
EventIdView getEvent();
Long getNumber();
Boolean getTrackingEnabled();
#Mapping(fetch = FetchStrategy.MULTISET)
Set<TransferDTO> getTransfers();
#Mapping(fetch = FetchStrategy.MULTISET)
Set<InventoryRequestAssignmentDTO> getAssignment();
#Mapping(fetch = FetchStrategy.MULTISET)
Set<InventoryRequestNoteDTO> getNotes();
#Mapping("COUNT(*) FILTER (WHERE assignment.catalog IS NULL)")
Long getCompleteSetsQuantity();
#Mapping("COUNT(*) FILTER (WHERE assignment.catalog IS NOT NULL)")
Long getSpecificProductQuantity();
}
#EntityView(User.class)
public interface UserDTO {
#IdMapping
UUID getId();
// Other fields you need
}
#EntityView(Transfer.class)
public interface TransferDTO {
#IdMapping
UUID getId();
// Other fields you need
}
#EntityView(InventoryRequestAssignment.class)
public interface InventoryRequestAssignmentDTO {
#IdMapping
UUID getId();
// Other fields you need
}
#EntityView(InventoryRequestNote.class)
public interface InventoryRequestNoteDTO {
#IdMapping
UUID getId();
// Other fields you need
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
InventoryRequestDTO dto = entityViewManager.find(entityManager, InventoryRequestDTO.class, id);
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 i.e. have a repository similar to the following
#Repository
public interface InventoryRepository {
Page<InventoryRequestDTO> findAll(Specification specification, Pageable pageable);
}
It will only fetch what you tell it to. Enjoy!

Springboot How to query a many to many relationship

I have two entities lets call them Categories and Products. These two entities are mapped by a many to many relationship.
My problem is that i am trying to get category information from products. Trying this results in empty categories.
This is my code :
PersistenceEntity
#MappedSuperclass
public class PersistenceEntity implements Serializable {
private static final long serialVersionUID = 4056818895685613967L;
// Instance Variables
#Id
#Column(unique = true)
#GeneratedValue(strategy = GenerationType.TABLE)
protected Long id;
#JsonIgnore
#Temporal(javax.persistence.TemporalType.TIMESTAMP)
protected Date creationDate = new Date();
...Getters and Setters omitted for brevity
}
Category
#Entity
#Table(name = "category")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Category extends PersistenceEntity{
private static final long serialVersionUID = 1L;
#Column(nullable = false)
private String categoryName;
#Column(nullable = false)
private Boolean active;
#Column(nullable = true)
private String picture;
#JsonIgnore
private MetaData metadata;
#ManyToMany(fetch = FetchType.EAGER,mappedBy = "categories")
private Set<Product> products;
...Getters and Setters omitted for brevity
}
Product
#Entity
#Table(name = "products",uniqueConstraints = { #UniqueConstraint(columnNames = "productCode")})
#JsonIgnoreProperties(ignoreUnknown = true)
public class Product extends PersistenceEntity {
private static final long serialVersionUID = 8727166810127029053L;
#Column(name = "product_name")
private String name;
private String productImageUrl;
#JsonIgnore
#ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
#JoinTable(name="category_products",
joinColumns={#JoinColumn(name="product_id", unique = false)},
inverseJoinColumns={#JoinColumn(name="category_id", unique = false)})
private Set<Category> categories;
...Getters and Setters omitted for brevity
}
ProductServiceImplementation
#Service
public class ProductService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
#Autowired
private ProductRepository productRepository;
public List<Product> getProductsByShopId( Long id) {
List<Product> productList = new ArrayList<>();
productList = productRepository.findByShopId(id);
return productList;
}
public Set<Long> getCategoryIds(List<Product> products){
Set<Long> categoriesIDs = new HashSet<Long>();
for (Product product : products) {
product.getCategories().forEach(category -> {
categoriesIDs.add(category.getId());
});
}
return categoriesIDs;
}
}
The problem is getting the categoryIds that are mapped to the list of products.
How can i get CategoryIds from Product. My getCategoryIds function returns empty always
public Set<Long> getCategoryIds(List<Product> products){
Set<Long> categoriesIDs = new HashSet<Long>();
for (Product product : products) {
product.getCategories().forEach(category -> {
categoriesIDs.add(category.getId());
});
}
return categoriesIDs;
}

How to create One to many relationship in Springboot

I am trying to create an api for a user to have the ability to add products to a specific category such that when, getCategory by id is called it gives a result as follows:
{
"product": [
{
"productId": 1,
"productName": "TestProdut1"
},{
"productId": 2,
"productName": "TestProdut2"
}
],
"categoryId": 1,
"categoryName": "Test1",
"parentCategoryId": 123
}
Please note i am using a postgres database
This is what i have done so far but when i try to get a category there
is no response back. When using swagger the response comes back as no
content
Category Entity :
#Entity
#Table(name = "category")
public class Category {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "category_id", unique = true, nullable = false)
private Long id;
#Column(nullable = false)
private String categoryName;
#JsonIgnore
#OneToMany(fetch = FetchType.LAZY, mappedBy = "categories", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Product> products = new ArrayList<Product>();
#ManyToOne
#JoinColumn(name = "parent_id")
#JsonIgnore
private Category parentId;
#OneToMany(mappedBy = "parentId")
private List<Category> subCategories = new ArrayList<>();
}
Product Entity :
#Entity
#Table(name = "products")
public class Product {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "product_id")
private Long id;
private String name;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "category_id")
private Category categories;
}
Category Repository :
public interface CategoryRepository extends CrudRepository<Category, Long>{
public List<Category> findByCategoryName(String categoryName);
}
Category Service :
#Service
public class CategoryService {
#Autowired
private CategoryRepository categoryRepository;
public void addCategory(Category category) {
categoryRepository.save(category);
}
public List<Category> getAllCategories() {
List<Category> categoryList = new ArrayList<>();
categoryRepository.findAll().forEach(categoryList::add);
return categoryList;
}
public List<Category> getAllCategoriesByName(String categoryName) {
List<Category> categoryList = new ArrayList<>();
categoryList = categoryRepository.findByCategoryName(categoryName);
return categoryList;
}
public Optional<Category> getCategoryById(Long categoryId) {
Optional<Category> category = categoryRepository.findById(categoryId);
return category;
}
public void deleteCategory(Long id) {
categoryRepository.deleteById(id);
}
}
Category Controller :
#RestController
#Api(value = "CategoryAPI", produces = MediaType.APPLICATION_JSON_VALUE)
#RequestMapping("/ss")
public class CategoryController {
#Autowired
private CategoryService categoryService;
#RequestMapping(method=RequestMethod.POST , value="/category/add", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Boolean> addCategory(#RequestBody Category category) {
categoryService.addCategory(category);
return new ResponseEntity<Boolean>(true, HttpStatus.CREATED);
}
#RequestMapping(method= RequestMethod.GET, value="/category/get/by/id/{categoryId}")
public void getCategoryById(#PathVariable Long categoryId) {
categoryService.getCategoryById(categoryId);
}
#RequestMapping(method= RequestMethod.GET, value="/category/get/by/name/{categoryName}")
public void getCategoryByName(#PathVariable String categoryName) {
categoryService.getAllCategoriesByName(categoryName);
}
#RequestMapping(method= RequestMethod.GET, value="/all/category")
public void getCategories() {
categoryService.getAllCategories();
}
}
It is because you are having void return type when retrieving the list of categories and that is why you are not getting any response.
#RequestMapping(method= RequestMethod.GET, value="/category/get/by/name/{categoryName}")
public ResponseEntity<List<Category>> getCategoryByName(#PathVariable String categoryName) {
return new ResponseEntity<>(categoryService.getAllCategoriesByName(categoryName),HttpStatus.OK);
}

Fetching One to Many object in Hibernate

I've the following two entities,
User
#Entity
#EqualsAndHashCode
public class User extends BaseEntity{
#Getter #Setter
private String msid;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "sender")
#Getter
private List<Media> sentList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "receiver")
#Getter
private List<Media> receivedList;
protected User(){
super();
}
public User(String yguid) {
this();
this.yguid = yguid;
this.receivedList = new ArrayList<>();
this.sentList = new ArrayList<>();
}
}
Media
#Entity
#EqualsAndHashCode
public class Media extends BaseEntity{
#Getter #Setter
private String mediaId;
#Getter #Setter
private String url;
#ManyToOne
#JoinColumn(name="sender")
#Getter #Setter
private User sender;
#ManyToOne
#JoinColumn(name="receiver")
#Getter #Setter
private User receiver;
public Media() {
super();
}
public Media(String mediaId, String url, User sender, User receiver) {
this();
this.mediaId = mediaId;
this.url = url;
this.sender = sender;
this.receiver = receiver;
}
}
Both inherit from a BaseEntity
public abstract class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private final Long id;
public BaseEntity() {
id = null;
}
}
I want to fetch all Media for an user. This is my code
public List<Media> getReceivedMediaForUser(User user){
Session session = sessionFactory.openSession();
Query query = session.createQuery("FROM Media m WHERE m.receiver = :user");
//parse query to get result
session.close();
//
return null;
}
This doesn't compile, can someone help me form the right query and get the results. I'm new to Spring and Hibernate.
You can do it as shown below (It is an example to follow not solution. Implement solution accordingly you requirements ),
Query query = session.createSQLQuery(
"select * from stock s where s.stock_code = :stockCode")
.addEntity(Stock.class)
.setParameter("stockCode", "7277");
List result = query.list();
Your solution could be
Session session = sessionFactory.openSession();
Query query = session.createQuery("select * FROM Media m WHERE m.receiver = :user")
.addEntity(Media.class)
.setParameter("user", "xyz");
List result = query.list();
session.close();

Categories

Resources