Can't create entity object with map with custom object - spring-boot

Spring boot 2.5
I has entity Cart. One cart has many entities Product. In one cart has many products. So I try with #JoinColumn but I get error:
#Entity
public class Cart {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#OneToMany(mappedBy = "cart", fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
private Map<Product, Integer> products;
}
import javax.persistence.*;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "cart_id", nullable = false)
private Cart cart;
}
But when I try to run application I get error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mvcConversionService' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.format.support.FormattingConversionService]: Factory method 'mvcConversionService' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cartRepository' defined in com.myproject.eshop_orders.repo.CartRepository defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: com.myproject.eshop_orders.api.model.Cart.products[java.lang.Integer]

If you want a map you need to use #MapKeyJoinColumn. Something like this
#Entity
public class Cart {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#MapKeyJoinColumn(name="PRODUCT_ID")
#OneToMany(mappedBy = "cart", fetch = FetchType.EAGER,
cascade = CascadeType.ALL)
private Map<Product, Integer> products;
}

One cart has many different products.
Also I need to store quantity of products in cart (value in map)
Here my solution:
#Entity
public class Cart {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ElementCollection
#CollectionTable(name = "cart_products", joinColumns = #JoinColumn(name = "cart_id"))
#MapKeyJoinColumn(name = "product_id")
#Column(name = "product_qantity")
private Map<Product, Integer> products;
}
import javax.persistence.*;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "cart_id", nullable = false)
private Cart cart;
}
Is this a correct solution?

Related

hibernate mapping and joining table error

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like #JoinTable or #JoinColumn: com.company.entities.Customer.address
#Entity
#Table(name="Customers")
public class Customer {
#Id
#Column(name="customer_Id")
private int customerid;
#Column(name="Customer_Name")
private String name;
#Column (name="Customer_email")
private String email;
#Column(name="Mobile_No")
private int mobilNo;
#OneToMany(cascade= CascadeType.ALL,mappedBy="customer")
#JoinTable(name="Customer",joinColumns={
#JoinColumn(name="customer_Id", referencedColumnName="customerid")
},
inverseJoinColumns={
#JoinColumn(name="address_Id",referencedColumnName="addId")
})
private Map<String,Address> address=new HashMap<>();
#Entity
public class Address {
#Id
private int addId;
private String StreetName;
private String city;
private String state;
#ManyToOne(cascade=CascadeType.ALL)
private Customer customer;
}

Unable to fetch Orders(which are not deleted) for logged in user

I am trying to fetch orders for logged in User which I was able to do. But now I have to orders for logged in User which are not marked as deleted as well. I am facing issue to fetch these records using spring-data-jpa. Same scenario I want to implement on User End.I am getting below exception -
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-09-02 05:31:03.699 ERROR 220 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'adminController': Unsatisfied dependency expressed through field 'journeyFoodServiceImpl'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'journeyFoodServiceImpl' defined in file [C:\Users\TiaaUser\Desktop\AWS\journeyfood\target\classes\org\brahmakumaris\journeyfood\service\JourneyFoodServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'journeyFoodOrderRepository' defined in org.brahmakumaris.journeyfood.repository.JourneyFoodOrderRepository defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Using named parameters for method public abstract java.util.List org.brahmakumaris.journeyfood.repository.JourneyFoodOrderRepository.findOrderByUserIdAndNotDisabled(long,boolean) but parameter 'Optional[userId]' not found in annotated query 'SELECT j.orderId,j.headCount,j.dateOfDeparture,j.dateOfOrderPlaced,j.mealRetrievalTime,j.achar,
j.bread,j.jam,j.puri,j.thepla,j.roti,j.others from JourneyFoodOrder j INNER JOIN users u on u.userId=?1 WHERE j.isRemoved=:isRemoved'!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
Caused by: java.lang.IllegalStateException: Using named parameters for method public abstract java.util.List org.brahmakumaris.journeyfood.repository.JourneyFoodOrderRepository.findOrderByUserIdAndNotDisabled(long,boolean) but parameter 'Optional[userId]' not found in annotated query 'SELECT j.orderId,j.headCount,j.dateOfDeparture,j.dateOfOrderPlaced,j.mealRetrievalTime,j.achar,
j.bread,j.jam,j.puri,j.thepla,j.roti,j.others from JourneyFoodOrder j INNER JOIN users u on u.userId=?1 WHERE j.isRemoved=:isRemoved'!
at org.springframework.data.jpa.repository.query.JpaQueryMethod.assertParameterNamesInAnnotatedQuery(JpaQueryMethod.java:172)
at org.springframework.data.jpa.repository.query.JpaQueryMethod.<init>(JpaQueryMethod.java:139)
at org.springframework.data.jpa.repository.query.DefaultJpaQueryMethodFactory.build(DefaultJpaQueryMethodFactory.java:44)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:81)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:100)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [SELECT j.orderId,j.headCount,j.dateOfDeparture,j.dateOfOrderPlaced,j.mealRetrievalTime,j.achar,
j.bread,j.jam,j.puri,j.thepla,j.roti,j.others from org.brahmakumaris.journeyfood.entity.JourneyFoodOrder j INNER JOIN users u on u.userId=:userId WHERE j.isRemoved=:isRemoved]
at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
JourneyFoodOrder.java Here isRemoved is getting used for marking orders as deleted.
#Entity
public class JourneyFoodOrder{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long orderId;
private int headCount;
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date dateOfOrderPlaced;
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date dateOfDeparture;
#DateTimeFormat(pattern = "dd/MM/yyyy h:mm a")
private Date mealRetrievalTime;
#ManyToOne
private UserEntity user;
private int thepla;
private int puri;
private int roti;
private int achar;
private int jam;
private int bread;
private int others;
private boolean isRemoved;
//Getter setter and constructors
}
UserEntity.java Here isDisabled is used for marking User as disabled and enabled field for enabling(User verification via email).
#Entity
#Table(name="users")
public class UserEntity {
#Id
#Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private long userId;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "users_roles", joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "userId"), inverseJoinColumns = #JoinColumn(name = "role_id", referencedColumnName = "roleId"))
private Set<Role> roles;
#Column(nullable = false, length = 100)
private String nameOfCenter;
#Column(nullable = false, length = 100)
private String nameOfGuide;
#Column(nullable = false, length = 18)
private String contactNoOfGuide;
#Column(nullable = false, unique = true, length = 70)
private String email;
#Column(nullable = false, length = 70)
private String zone;
#Column(nullable = false, length = 70)
private String subZone;
#Column(length = 10)
private Integer pincode;
private Date dateCreated;
private boolean isDisabled;
#Column(nullable = false, length = 150)
private String password;
#Column(nullable = false)
#Type(type = "org.hibernate.type.NumericBooleanType")
private boolean enabled;//whether account is verified using email or not
#OneToMany(mappedBy = "user")
#Fetch(FetchMode.JOIN)
private List<JourneyFoodOrder> order;
//Getters, setters and constructor
}
JourneyFoodOrderRepository.java
#Repository
public interface JourneyFoodOrderRepository extends JpaRepository<JourneyFoodOrder, Long>{
#Override
void delete(JourneyFoodOrder order);
#Modifying
#Query("update JourneyFoodOrder j set j.isRemoved =true where j.orderId =:id")
void updateIsRemoved(#Param("orderId")Long orderId);
List<JourneyFoodOrder> findByIsRemoved(boolean isRemoved);
#Modifying
#Query("SELECT j.orderId,j.headCount,j.dateOfDeparture,j.dateOfOrderPlaced,j.mealRetrievalTime,j.achar,\r\n"
+ "j.bread,j.jam,j.puri,j.thepla,j.roti,j.others from JourneyFoodOrder j INNER JOIN users u on u.userId=:userId WHERE j.isRemoved=:isRemoved")
List<JourneyFoodOrder> findOrderByUserIdAndNotDisabled(#Param("userId") long userId, #Param("isRemoved") boolean isRemoved);
}
Please help me out in resolving this issue.
In your for findOrderByUserIdAndNotDisabled method query, you have set method parameter as this j.isRemoved=:isRemoved. It should be change to j.isRemoved= ?2.
Here is the corrected Query
#Query("SELECT j.orderId,j.headCount,j.dateOfDeparture,j.dateOfOrderPlaced,j.mealRetrievalTime,j.achar,"
+ "j.bread,j.jam,j.puri,j.thepla,j.roti,j.others from JourneyFoodOrder j INNER JOIN users u on u.userId=?1 WHERE j.isRemoved= ?2")
I was using wrong Entity name causing this issue -
#Query("SELECT j.orderId,j.headCount,j.dateOfDeparture,j.dateOfOrderPlaced,j.mealRetrievalTime,j.achar,\r\n"
+ "j.bread,j.jam,j.puri,j.thepla,j.roti,j.others from JourneyFoodOrder j INNER JOIN UserEntity u on u.userId=:userId WHERE j.isRemoved=:isRemoved")
List<JourneyFoodOrder> findOrderByUserIdAndNotDisabled(#Param("userId") long userId, #Param("isRemoved") boolean isRemoved);
editing users to UserEntity did resolved my issue.

Getting BeanCreationException: Unknown entity name: int : Hibernate with JPA

I am new to Hibernate, I have written a entity class as below as per the table definition:
#Embeddable
class APK implements Serializable {
private String bId;
private int version; <---THIS IS CAUSING PROBLEM
}
#Entity
#Table(name = "a")
public class A implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private APK aPK;
#MapsId("bId")
#ManyToOne
#JoinColumn(name = "b_id", referencedColumnName = "id")
private B b;
#MapsId("version")
#Column(name = "version")
private int version;
#Column(name = "name")
private String name;
}
While, I am starting the server, I am getting following exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'entityManagerFactory' defined in class path resource
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation
of init method failed; nested exception is org.hibernate.AnnotationException: Unknown entity
name: int
In table definition type of version is int. But to fix this I even tried to change the version type to Long, Integer but always I am getting similar error. Any idea how should I fix this issue ?
Remove #MapsId("version") annotation from private int version;, cause int is not an Entity. Refer here for more details.

How to write query for many to one mapped entity in JpaRepository

I have two entities and mapped those using many-to-one annotation but after writing a query for find object using another table id I got an error when I commented out that line and method called to that application work but I want to implement that functionality and please help me
These are my entity classes:
#Entity
#Table(name = "Contract")
public class Contract implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "contractId")
private long contractId;
#Column(name="start_date")
private Date st_date;
#Column(name="end_date")
private Date end_date;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "hotel_id", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIgnore
private Hotel hotel;
// getters and setters
Second entity
#Entity
#Table(name="Hotel")
public class Hotel {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="hotel_id")
private long hotel_id;
#Column(name="hotel_name")
private String hotel_name;
#Column(name="hotel_location")
private String hotel_location;
#Column(name="hotel_email")
private String hotel_email;
#Column(name="hotel_telephone")
private String hotel_telephone
// getters and setters
My contract service class
#Service
public class ContractService {
#Autowired
private ContractRepository contractRepository;
#Autowired
private HotelRepository hotelRepository;
public List<Contract> getAllContracts(){
return contractRepository.findAll();
}
public List<Contract> findByHotelId(Long hotelId,Pageable pageable){
return contractRepository.findByHotelId(hotelId, pageable);
}
public ResponseEntity<?> deleteContract(Long hotelId, Long contractId)
{
return contractRepository.findByIdAndHotelId(contractId,
hotelId).map(Contract -> {
contractRepository.delete(Contract);
return ResponseEntity.ok().build();
}).orElseThrow(() -> new ResourceNotFoundException("Comment not found
with ContractId " + contractId + " and hotelId " + hotelId));
}
My contract repository
#Repository
public interface ContractRepository extends JpaRepository<Contract, Long> {
List<Contract> findByHotelId(Long hotelId, Pageable pageable);
Optional<Contract> findByIdAndHotelId(Long id, Long hotelId);
}
I got this error when running my project
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contractController': Unsatisfied dependency expressed through field 'contractService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contractService': Unsatisfied dependency expressed through field 'contractRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contractRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.sunTravel.sunRest.repository.ContractRepository.findByHotelId(java.lang.Long,org.springframework.data.domain.Pageable)! No property id found for type Hotel! Traversed path: Contract.hotel.
First Solution: based on your stack trace, Spring data is looking for id variable (primary key) in your Hotel class. So please change private long hotel_id; to private long id;
Another solution (no need to change anything just add your own query):
write your own JPA query using #Query.
Example:
#Query("SELECT contract from Contract as contract where contract.hotel.hotel_id = :hotelId")
List<Contract> findByHotelId(Long hotelId, Pageable pageable);
You should rename your Primary Key from hotel_id to id then only your repository method will work.
#Entity
#Table(name="Hotel")
public class Hotel {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="hotel_id")
private long id;
#Column(name="hotel_name")
private String hotel_name;
#Column(name="hotel_location")
private String hotel_location;
#Column(name="hotel_email")
private String hotel_email;
#Column(name="hotel_telephone")
private String hotel_telephone
// getters and setters

Building several one-to-many relationships

It implements the model as seen below:
I implement three classes of models:
#Entity
public class Home implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(mappedBy = "home")
private Set<UserHome> userHomes;
}
#Entity
public class UserHome implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
#JoinColumn(name = "home_id")
private Home home;
#OneToMany(mappedBy = "userhome")
private Set<Key> keys;
}
#Entity
public class Key implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
#JoinColumn(name = "userhome_id")
private UserHome userHome;
}
When you try to compile it gets an error:
Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.example.homeUser.Key.userhome in com.example.homeUser.UserHome.keys
I do not know what's wrong with my code?
There is a typo in your code, the lowercase h in userhome:
#OneToMany(mappedBy = "userhome")
private Set<Key> keys;
Should be (uppercase H):
#OneToMany(mappedBy = "userHome")
private Set<Key> keys;
The fields/properties you reference in a field like mappedBy should have the exact name and case of the field in the JavaBean.

Resources