how to rectify this mapping exception( Use of #OneToMany or #ManyToMany targeting an unmapped class) - spring

Hi I am getting some mapping exception please follow the below error
org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: com.cmr.daos.child.domain.Child.medications[com.cmr.daos.child.domain.Medications]
at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1185)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:710)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:645)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:65)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1716)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1423)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:720)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
... 62 more
My domain class:
public class Child extends AuditProperties implements java.io.Serializable {
#Expose private Long childId;
#Expose private String firstName;
#Expose private String lastName;
private Set<Allergies> allergies = new HashSet<Allergies>();
private Set<Medications> medications = new HashSet<Medications>();
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "child")
#JsonManagedReference
public Set<Medications> getMedications() {
return this.medications;
}
public void setMedications(Set<Medications> medications) {
this.medications = medications;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "child")
#JsonManagedReference
public Set<Allergies> getAllergies() {
return this.allergies;
}
public void setAllergies(Set<Allergies> allergies) {
this.allergies = allergies;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "CHILD_ID", unique = true, nullable = false)
public Long getChildId() {
return this.childId;
}
public void setChildId(Long childId) {
this.childId = childId;
}
#Column(name = "FIRST_NAME", nullable = false, length = 64)
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "LAST_NAME", nullable = false, length = 64)
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Here my mapped classs:
public class Medications extends AuditProperties implements java.io.Serializable{
#Expose private Long medicationId;
#Expose private String hasMedication;
#Expose private String medicationType;
#Expose private transient Child child;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "CHILD_ID")
#JsonBackReference
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "MEDICATION_ID", unique = true, nullable = false)
public Long getMedicationId() {
return medicationId;
}
public void setMedicationId(Long medicationId) {
this.medicationId = medicationId;
}
#Column(name = "HAS_MEDICATION", nullable = false, length = 3)
public String getHasMedication() {
return hasMedication;
}
public void setHasMedication(String hasMedication) {
this.hasMedication = hasMedication;
}
#Column(name = "MEDICATION_TYPE", length = 64)
public String getMedicationType() {
return medicationType;
}
public void setMedicationType(String medicationType) {
this.medicationType = medicationType;
}
}
Here another mapped class:
#Entity
#Table(name = "ALLERGIES")
public class Allergies extends AuditProperties implements java.io.Serializable {
#Expose private Long allergyId;
#Expose private String hasAllergies;
#Expose private String allerigyType;
#Expose private transient Child child;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "CHILD_ID")
#JsonBackReference
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "ALLERGY_ID", unique = true, nullable = false)
public Long getAllergyId() {
return allergyId;
}
public void setAllergyId(Long allergyId) {
this.allergyId = allergyId;
}
#Column(name = "HAS_ALLERGIES", length = 3)
public String getHasAllergies() {
return hasAllergies;
}
public void setHasAllergies(String hasAllergies) {
this.hasAllergies = hasAllergies;
}
#Column(name = "ALLERIGY_TYPE", length = 20)
public String getAllerigyType() {
return allerigyType;
}
public void setAllerigyType(String allerigyType) {
this.allerigyType = allerigyType;
}
}
Here i mentioned one child class, allergy class and medication class.Here i mapped child object to both the classes(allergy,medications) then i will get this exception.please help me abot this exception

As the exception says:
Use of #OneToMany or #ManyToMany targeting an unmapped class:
com.cmr.daos.child.domain.Child.medications[com.cmr.daos.child.domain.Medications]
Hibernate is trying to find the entity Medications that represents the property medications in your Child class.
Looking at the etities everything looks good, so I assume you missed to place #Entity for Medications class or you missed to mention about this entity in hibernate.cfg.xml file.

Related

Error mapping OneToMany or ManyToOne unmapped class

I have this problem :
Error creating bean with name 'ICustomerDao' defined in com.biblio.fr.biblio.repository.ICustomerDao 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.biblio.fr.biblio.entite.Book.loans[com.biblio.fr.biblio.entite.Loan]
this is my code :
#Entity
#Table(name = "BOOK")
public class Book {
private Integer id;
private String title;
private String isbn;
private LocalDate releaseDate;
private LocalDate registerDate;
private Integer totalExamplaries;
private String author;
private Category category;
Set<Loan> loans = new HashSet<Loan>();
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "BOOK_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "TITLE", nullable = false)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name = "ISBN", nullable = false, unique = true)
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
#Column(name = "RELEASE_DATE", nullable = false)
public LocalDate getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(LocalDate releaseDate) {
this.releaseDate = releaseDate;
}
#Column(name = "REGISTER_DATE", nullable = false)
public LocalDate getRegisterDate() {
return registerDate;
}
public void setRegisterDate(LocalDate registerDate) {
this.registerDate = registerDate;
}
#Column(name = "TOTAL_EXAMPLARIES")
public Integer getTotalExamplaries() {
return totalExamplaries;
}
public void setTotalExamplaries(Integer totalExamplaries) {
this.totalExamplaries = totalExamplaries;
}
#Column(name = "AUTHOR")
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
#ManyToOne(optional = false)
#JoinColumn(name = "CAT_CODE", referencedColumnName = "CODE")
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
// #OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.book", cascade =
// CascadeType.ALL)
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk", cascade = CascadeType.ALL)
public Set<Loan> getLoans() {
return loans;
}
public void setLoans(Set<Loan> loans) {
this.loans = loans;
}
}
public class Loan implements Serializable {
private static final long serialVersionUID = 144293603488149743L;
private LoanId pk = new LoanId();
private LocalDate beginDate;
private LocalDate endDate;
private LoanStatus status;
#EmbeddedId
public LoanId getPk() {
return pk;
}
public void setPk(LoanId pk) {
this.pk = pk;
}
#Column(name = "BEGIN_DATE", nullable = false)
public LocalDate getBeginDate() {
return beginDate;
}
public void setBeginDate(LocalDate beginDate) {
this.beginDate = beginDate;
}
#Column(name = "END_DATE", nullable = false)
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
#Enumerated(EnumType.STRING)
#Column(name = "STATUS")
public LoanStatus getStatus() {
return status;
}
public void setStatus(LoanStatus status) {
this.status = status;
}
}
#Embeddable
public class LoanId implements Serializable {
private static final long serialVersionUID = 3912193101593832821L;
private Book book;
private Customer customer;
private LocalDateTime creationDateTime;
public LoanId() {
super();
}
public LoanId(Book book, Customer customer) {
super();
this.book = book;
this.customer = customer;
this.creationDateTime = LocalDateTime.now();
}
#ManyToOne
public Book getBook() {
return book;
}
public void setBook(Book bbok) {
this.book = bbok;
}
#ManyToOne
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
#Column(name = "CREATION_DATE_TIME")
public LocalDateTime getCreationDateTime() {
return creationDateTime;
}
public void setCreationDateTime(LocalDateTime creationDateTime) {
this.creationDateTime = creationDateTime;
}
}
#Table(name = "CUSTOMER")
public class Customer {
private Integer id;
private String firstName;
private String lastName;
private String job;
private String address;
private String email;
private LocalDate creationDate;
Set<Loan> loans = new HashSet<Loan>();
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "CUSTOMER_ID")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "FIRST_NAME", nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "LAST_NAME", nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "JOB")
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
#Column(name = "ADDRESS")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "EMAIL", nullable = false, unique = true)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "CREATION_DATE", nullable = false)
public LocalDate getCreationDate() {
return creationDate;
}
public void setCreationDate(LocalDate creationDate) {
this.creationDate = creationDate;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.customer", cascade = CascadeType.ALL)
public Set<Loan> getLoans() {
return loans;
}
public void setLoans(Set<Loan> loans) {
this.loans = loans;
}
}
public class Category {
public Category() {
}
public Category(String code, String label) {
super();
this.code = code;
this.label = label;
}
private String code;
private String label;
#Id
#Column(name = "CODE")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name = "LABEL", nullable = false)
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
#Repository
public interface ICategoryDao extends JpaRepository<Category, Integer> {
}
public interface ICustomerDao extends JpaRepository<Customer, Integer> {
public Customer findCustomerByEmailIgnoreCase(String email);
public List<Customer> findCustomerByLastNameIgnoreCase(String lastName);
}
I can't see where is the problem of my oneTomany annotation
Anyone can, i help me.

Not null reference a null or transient value

So i am trying to achieve oneToone relationship between two entity classes.First class is a customer entity class which have two foreign keys buyer_id and seller_id.So what i want initially is that when the user fills the initial credentials in the website the buyer_id and seller_id field should be null and after the user fills the required information for the buyer or seller i will update the row of the corresponding customer and add the buyer_id and seller_id.But when i try to create a customer entry i am getting this error that buyer_id cannot be null?
This is my customer table
#Entity
#Table(name = "Customer")
public class Customer {
public enum Status{
ACTIVE,
IN_ACTIVE
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#OneToOne(fetch = FetchType.LAZY,optional = true,cascade=CascadeType.ALL)
#JoinColumn(name = "seller_id",nullable = true,referencedColumnName = "id",updatable = true)
#Basic(optional = true)
private Seller seller_id;
#OneToOne(fetch=FetchType.LAZY,optional = true,cascade=CascadeType.ALL)
#JoinColumn(name = "buyer_id", nullable = true,referencedColumnName="id",updatable = true)
#Basic(optional = true)
private Buyer buyer_id;
#OneToOne(fetch=FetchType.LAZY,optional = false,cascade = CascadeType.ALL)
#JoinColumn(name = "user_id",nullable = false,unique = true,referencedColumnName = "id")
private User user_id;
public Buyer getBuyer_id() {
return buyer_id;
}
public void setBuyer_id(Buyer buyer_id) {
this.buyer_id = buyer_id;
}
#Column(name = "Name")
String name;
#Enumerated(EnumType.STRING)
#Column(name = "Status")
private Status status;
public Customer(String name,Status status){
this.name=name;
this.status = status;
}
public Customer(){
}
public Seller getSeller_id() {
return seller_id;
}
public void setSeller_id(Seller seller_id) {
this.seller_id = seller_id;
}
public User getUser_id() {
return user_id;
}
public void setUser_id(User user_id) {
this.user_id = user_id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user_id;
}
public void setUser(User user) {
this.user_id = user;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
This is my buyer table
#Entity
#Table(name="Buyer")
public class Buyer {
#Id
#Column(name = "id") private long id;
#Column(name = "GSTIN")
String GSTIN;
#Column(name = "Legal_Document")
#Lob
private byte[] legalDocument;
#OneToOne(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "buyer_id")
#JsonIgnore
private Customer customer;
#Column(name = "Authorized_person_name")
String authorized_person_name;
#Column(name = "Authorized_person_email")
String authorized_person_email;
}
This is my seller table
#Entity
#Table(name = "Seller")
public class Seller {
#Id
#Nullable
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "GSTIN")
private String GSTIN;
#Column(name = "GST_Document")
#Lob
private byte[] gst_document;
#OneToOne(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "seller_id")
#JsonIgnore
private Customer customer;
// #OneToOne(fetch = FetchType.LAZY,
// cascade = CascadeType.ALL,
// mappedBy = "sellerId")
// #JsonIgnore
// private PickupAddress pickupAddress;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
public String getGSTIN() {
return GSTIN;
}
public void setGSTIN(String GSTIN) {
this.GSTIN = GSTIN;
}
public byte[] getGst_document() {
return gst_document;
}
public void setGst_document(byte[] gst_document) {
this.gst_document = gst_document;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

#Id Not Mapped For Specific Entity In A Spring-Boot Controller

I have two entities Employee and Department and each have a Spring Web #RestController annotated class with update methods i.e. Http PUT.
For some strange reason (and likely a blindingly obvious solution) whenever the PUT is called for the Employee class, the ID in the JSON payload is NOT mapped to the id class of the Employee entity but it works perfectly for the Department entity.
Employee class:
Entity
#Table(name = "EMPLOYEE")
public class Employee implements Serializable, Identity<Long>, Deleted
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "NAME")
private String name;
#ManyToOne
#Where(clause = "is_deleted = false")
private Department department;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "EMP_QUAL", joinColumns = #JoinColumn(name = "EMPLOYEE_ID"), inverseJoinColumns = #JoinColumn(name = "QUALIFICATION_ID"))
#WhereJoinTable(clause = "IS_DELETED = false")
#SQLDelete(sql = "UPDATE `EMP_QUAL` SET IS_DELETED = true where EMPLOYEE_ID = ? and QUALIFICATION_ID = ? and IS_DELETED = False")
private Set<Qualification> qualifications;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "EMP_PROJ", joinColumns = #JoinColumn(name = "emp_id"), inverseJoinColumns = #JoinColumn(name = "proj_id"))
#Where(clause = "is_deleted = false")
private Set<Project> projects;
#JsonIgnore
#Column(name = "is_deleted", nullable = false)
private Boolean isDeleted = false;
#Override
public Long getId()
{
return this.id;
}
#Override
public void setId(final Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(final String name)
{
this.name = name;
}
public Set<Project> getProjects()
{
return projects;
}
public void setProjects(final Set<Project> projects)
{
this.projects = projects;
}
public Department getDepartment()
{
return department;
}
public void setDepartment(final Department department)
{
this.department = department;
}
public Set<Qualification> getQualifications()
{
return qualifications;
}
public void setQualifications(final Set<Qualification> qualifications)
{
this.qualifications = qualifications;
}
public Boolean isDeleted()
{
return isDeleted;
}
public void setDeleted(final Boolean deleted)
{
isDeleted = deleted;
}
}
Department class:
#Entity
#Table(name = "DEPARTMENT")
public class Department implements Serializable, Identity<Long>, Deleted
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#OneToMany(fetch = FetchType.EAGER)
#WhereJoinTable(clause = "is_deleted = false")
#JoinTable(name = "DEPARTMENT_EMPLOYEE", joinColumns = {#JoinColumn(name = "department_id")},
inverseJoinColumns = {#JoinColumn(name = "employee_id")})
#SQLDelete(sql = "UPDATE DEPARTMENT_EMPLOYEE SET is_deleted = true where department_id = ? and employee_id = ? and is_deleted = false")
private Set<Employee> departmentMembers;
#Column(name = "is_deleted", nullable = false)
private Boolean isDeleted;
#Override
public Long getId()
{
return this.id;
}
#Override
public void setId(final Long id)
{
this.id = id;
}
#Override
public Boolean isDeleted()
{
return this.isDeleted;
}
#Override
public void setDeleted(final Boolean isDeleted)
{
this.isDeleted = isDeleted;
}
public String getName()
{
return name;
}
public void setName(final String name)
{
this.name = name;
}
public Set<Employee> getDepartmentMembers()
{
return departmentMembers;
}
public void setDepartmentMembers(final Set<Employee> departmentMembers)
{
this.departmentMembers = departmentMembers;
}
}
When call PUT /employees/{id}:
Calling PUT /departments/{id}:
As you can see in the screenshots of the debugger the id field of Department is populated while it is null in Employee. I'm testing this with Swagger and I am setting the ID in the payload. I don't have any specific Jackson configuration set I just use Spring boot's default but I cannot work out why only in Employee the id field is never mapped.
Employee body:
{
"id":1,
"name": "New Name"
}
Department body:
{
"id":2,
"name": "chemistry",
"deleted":false
}
The issue was due to a Jackson annotation #JsonIdentityInfo on another entity Project which is has a relationship with Employee:
#Entity
#Table(name = "PROJECT")
public class Project implements Serializable, Identity<Long>, Deleted
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "EMP_PROJ", joinColumns = #JoinColumn(name = "proj_id"), inverseJoinColumns = #JoinColumn(name = "emp_id"))
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "id")
#Where(clause = "is_deleted = false")
private Set<Employee> employees;

JPA repository null pointer exception for many to one mapping with composite primary key

Post class
one to many mapping
Composite primary key using id
I am getting null pointer exception when I make get request for getting comments
#Entity
#Table(name = "posts")
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(max = 100)
#Column(unique = true)
private String title;
#NotNull
#Size(max = 250)
private String description;
#NotNull
#Lob
private String content;
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "posted_at")
private Date postedAt = new Date();
#NotNull
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "last_updated_at")
private Date lastUpdatedAt = new Date();
#OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "post")
private Set<Comment> comments = new HashSet<>();
public Post() {
}
public Post(String title, String description, String content) {
this.title = title;
this.description = description;
this.content = content;
}
//getters and setters
}
Comment class
many to one mapping with composite primary keys using #Idclass
#Entity
#IdClass(CommentId.class)
#Table(name = "comments")
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Lob
private String text;
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "post_id", nullable = false)
private Post post;
public Comment() {
}
public Comment(String text) {
this.text = text;
}
//getters and setters
}
Id class
CommentId
public class CommentId implements Serializable {
private static final long serialVersionUID = 1L;
private Post post;
private Long id;
public CommentId(Post post, Long id) {
super();
this.post = post;
this.id = id;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result+ ((post == null) ? 0 : post.hashCode());
result = prime * result ;
return result;
}
public boolean equals(Object object) {
if (object instanceof CommentId) {
CommentId pk = (CommentId)object;
return id.equals(pk.id) && post == pk.post;
} else {
return false;
}
}
//getters and setters
}
repositories
PostRepository
CommentRepository
#Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
#Repository
public interface CommentRepository extends JpaRepository<Comment, Long>
{
}
Controller class get request and I am using mysql database
#RestController
#RequestMapping("/demo")
public class Controller {
#Autowired
PostRepository ps;
CommentRepository cs;
#GetMapping("/post")
public List<Post> getAll(){
return ps.findAll();
}
#GetMapping("/comment")
public List<Comment> getAllcom(){
return cs.findAll();
}
}

Spring Data rest how to perform CRUD on #manytomany relation ,composite table with extra column

I am unable to perform CRUD via json POST from restful client Postman on Composite table having extra column .I am using Spring boot ,spring data rest and spring JPA.
I have 3 tables in data base
-user
-competency
-user_competency (join/composite table with extra column)
Here are my classes
User
#Entity
#Table(name = "\"user\"", schema = "public")
#JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "userId")
public class User implements java.io.Serializable {
private Long userId;
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id", unique = true, nullable = false)
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);
#OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL}, mappedBy = "user")
public Set<UserCompetency> getUserCompetencies() {
return this.userCompetencies;
}
public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
this.userCompetencies = userCompetencies;
}
}
Competency
#Entity
#Table(name = "competency", schema = "public")
#JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "competencyId")
public class Competency implements java.io.Serializable {
private Long competencyId;
private Set<UserCompetency> userCompetencies = new HashSet<UserCompetency>(0);
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "competency_id", unique = true, nullable = false)
public Long getCompetencyId() {
return this.competencyId;
}
public void setCompetencyId(Long competencyId) {
this.competencyId = competencyId;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "competency")
public Set<UserCompetency> getUserCompetencies() {
return this.userCompetencies;
}
public void setUserCompetencies(Set<UserCompetency> userCompetencies) {
this.userCompetencies = userCompetencies;
}
}
UserCompetency
#Entity
#Table(name = "user_competency", schema = "public")
#JsonIdentityInfo(
generator =ObjectIdGenerators.IntSequenceGenerator.class,
property = "id")
public class UserCompetency implements java.io.Serializable {
private UserCompetencyId id;
private Level level;
private User user;
private Competency competency;
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "competencyId", column = #Column(name = "competency_id", nullable = false)),
#AttributeOverride(name = "userId", column = #Column(name = "user_id", nullable = false)) })
public UserCompetencyId getId() {
return this.id;
}
public void setId(UserCompetencyId id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "level_id")
public Level getLevel() {
return this.level;
}
public void setLevel(Level level) {
this.level = level;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
public Competency getCompetency() {
return this.competency;
}
public void setCompetency(Competency competency) {
this.competency = competency;
}
}
UserCompetencyId
#Embeddable
public class UserCompetencyId implements java.io.Serializable {
private Long competencyId;
private Long userId;
public UserCompetencyId() {
}
public UserCompetencyId(Long competencyId, Long userId) {
this.competencyId = competencyId;
this.userId = userId;
}
#Column(name = "competency_id", nullable = false)
public Long getCompetencyId() {
return this.competencyId;
}
public void setCompetencyId(Long competencyId) {
this.competencyId = competencyId;
}
#Column(name = "user_id", nullable = false)
public Long getUserId() {
return this.userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof UserCompetencyId))
return false;
UserCompetencyId castOther = (UserCompetencyId) other;
return (this.getCompetencyId() == castOther.getCompetencyId()) && (this.getUserId() == castOther.getUserId());
}
}
Suppose i have already record in User and Competency tables and i want to assocaite both i am trying to post like this ,but it give me error of 405 Method Not Allowed.
help required ,what should be structure of json to be posted User will already exist and competency will might exist or new can be added and associated with existing user.
With this code I was able to post a new relation:
UserCompetency.class
#Entity
#Table(name = "user_competency")
#IdClass(UserCompetencyId.class)
public class UserCompetency implements java.io.Serializable {
#Id #ManyToOne
#JoinColumn(name = "competency_id", nullable = false, insertable = false, updatable = false)
private Competency competency;
#Id #ManyToOne
#JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
private User user;
UserCompetencyId.class
public class UserCompetencyId implements java.io.Serializable {
private Long competency;
private Long user;
public UserCompetencyId() {
}
public UserCompetencyId(Long competency, Long user) {
this.competency = competency;
this.user = user;
}
UserCompetencyRepository.class
public interface UserCompetencyRepository extends JpaRepository<UserCompetency, UserCompetencyId> {
}
POST http://localhost:8080/userCompetencies
{
"competency": "/competencies/2"
, "user": "/user/4"
}
Apparently there seems to be no "natural/easy" way to get what you want. But there is a promissing project for integrating embeddables by extending the serialization process: https://github.com/gregturn/embeddable-spring-data-rest
UserCompetencyIdJacksonModule, UserCompetencyIdSerializer, ..
Then you should be able PATCH (not POST) your JSON from above.

Resources