hibernate mapping and joining table error - spring-boot

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;
}

Related

springboot Entity With cascadeType remove

I am not quit famililar with relationship between table,but i want to make a one-to-one relationship with table history and news.What i want is when the news is deleted, the history will also be deleted by on the news_id.But it give an error when i set the entity like this:
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 java.lang.NullPointerException: Cannot invoke "org.hibernate.mapping.PersistentClass.getTable()" because "classMapping" is null
My News:
#Id
#GeneratedValue
#OneToOne(cascade = {CascadeType.REMOVE})
#JoinColumn(name = "History_news_id")
private int id;
private String title;
private String Url;
private String content;
private String image;
private LocalDate date;
private int category;
My History:
#Id
#GeneratedValue
private int id;
private String username;
private int user_id;
#OneToOne(mappedBy = "History")
private int news_id;
private LocalDate date;
private String title;

How to give multiple columns as primary key in entity - JPA

I have 3 entities - Course, Module, Timeline
In the timeline entity - I want to give 2 keys as primary key i.e Composite Key. How am I supposed to give that. Please tell me about the changes that are to be done in the code below:
Course:
#Id
#Column(name = "id")
Integer courseId;
#Column(name = "course_name")
String course_name;
Module:
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "module_id")
Integer module_id;
#Column(name = "module_type")
String module_type;
#Column(name = "module_name")
String module_name;
#Column(name = "duration")
Integer duration;
#OneToOne( cascade = CascadeType.ALL)
private Course course;
Timeline:
#Id
#Column(name = "timeline_id")
Integer timeline_id;
#ManyToOne( cascade=CascadeType.ALL )
private Module module;
#ManyToOne( cascade = CascadeType.ALL)
private Course course;
Now here in timeline, I want to have course_id and timeline_id as primary keys. Please help.
Thank you in advance.
Update:
I tried using Embeddable and EmbeddedId:
#Embeddable
public class TimelineId implements Serializable{
private Integer course_id;
private Integer timelineId;
getters and setters
hashcode and equals
}
Module:
#Entity
#Table (name = "timeline")
public class Timeline {
#EmbeddedId
private TimelineId timelinepk;
#ManyToOne( cascade=CascadeType.ALL )
private Module module;
#ManyToOne( cascade = CascadeType.ALL)
private Course course;
}
But this gives an 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: No identifier specified for entity: com.scb.axess.playbook.model.Timeline
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
There are multiple possibilities to solve your problem:
Possibility 1: Using IdClass
Defining the IdClass type
This class has to implement the Serializable interface and the equals(..) and hashCode() methods. The class holds the parts of the composite primary key.
public class TimelineId implements Serializable {
private Integer timelineId;
private Integer courseId;
// getters & setters
#Override
public int hashCode() {
// your impl of hashCode
}
#Override
public boolean equals(Object obj) {
// your impl of equals
}
}
Modify your Timeline class
Here the #IdClass annotation is added to the entity class. Further, the class holds the same fields like the IdClass type (name and type should be identical), but annotated with #Id.
#Entity
#IdClass(TimelineId.class)
public class Timeline {
#Id
#Column(name = "timeline_id")
private Integer timelineId;
#Id
#Column(name = "course_id")
private Integer courseId;
#ManyToOne
#JoinColumn(name = "module_id")
private Module module;
// getters & setters
}
Possibility 2: Using EmbeddedId
Defining the EmbeddedId type
This class also holds the parts of the composite primary key.
#Embeddable
public class TimelineId {
#Column(name = "timeline_id")
private Integer timelineId;
#Column(name = "course_id")
private Integer courseId;
// getters & setters
}
Modify your Timeline class
In this case the single parts of the composite primary key can be omitted. Only a field of the embedded key type annotated with #EmbeddedId is defined.
#Entity
public class Timeline {
#EmbeddedId
private TimelineId timelineId;
#ManyToOne
#JoinColumn(name = "module_id")
private Module module;
// getters & setters
}
In both cases the corresponding repositories should be defined like this (TimelineId has to be used for parameter type ID) (here, JpaRepository is used):
public interface TimelineRepository extends JpaRepository<Timeline, TimelineId> {}
**Possibility 3: Don't use a composite PK, but make the columns unique**
Modify your Timeline class
#Entity
#Table(uniqueConstraints = {
#UniqueConstraint(columnNames = {
"course_id", "module_id"
})
})
public class Timeline {
#Id
#Column(name = "timeline_id")
Integer timeline_id;
#ManyToOne( cascade=CascadeType.ALL)
#JoinColumn(name = "module_id)
private Module module;
#ManyToOne( cascade = CascadeType.ALL)
#JoinColumn(name = "course_id)
private Course course;
// getters & setters
}

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.

Can't create entity object with map with custom object

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?

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

Resources