Spring Cannot add foreign key constraint #ManyToOne - java

I've tried to make this Entity:
#Entity
#Table(name = "rate")
public class Rate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "rate_id")
private Long id;
#ManyToOne
#JoinColumn(name = "user_id")
private User answerer;
#ManyToOne
#JoinColumn(name = "answer_id")
private Answer answer;
#Column(name = "rate_rate")
private Integer rate = AnswerConstants.MAX_RATE;
//pluss getter-setters
}
Unfortunately, I get this error:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Unable to execute schema management to JDBC target [alter table rate add constraint FK8totaejp8tp48clsoikn05fn2 foreign key (answer_id) references answer (answer_id)]
I've Googled for about an hour but I could not found the solution. Can you help me? Why am I getting this?
Additionally: spring.jpa.hibernate.ddl-auto=update, if I turn it off, it solves the problem but I do not want to do that just because of this.
The Answer class looks like this:
#Entity
#Table(name = "answer")
public class Answer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "answer_id")
private Long id;
#Column(name = "answer_text")
#NotEmpty
private String answerText;
#ManyToOne
#JoinColumn(name = "user_id")
private User answerCreator;
#ManyToOne
#JoinColumn(name = "question_id")
private Question question;
#Column(name = "answer_creation_date")
#NotNull
private Date creationDate = new Date();
#Column(name = "answer_rate")
private Long answerRate = 1l;
//plus getters-setters
}
And the User class:
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private Long id;
#Column(name = "email")
#Email(message = "*Please provide a valid Email")
#NotEmpty(message = "*Please provide an email")
private String email;
#Column(name = "password")
#Length(min = 5, message = "*Your password must have at least 5 characters")
#NotEmpty(message = "*Please provide your password")
#Transient
private String password;
#Column(name = "active")
private int active;
#ManyToMany()
#JoinTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
//Plus getters-setters
}

Try passing name with referencedColumnName with #JoinColumn annotation. It worked for me.
#ManyToOne(optional = false)
#JoinColumn(name = "userTypeId", referencedColumnName = "id",nullable = false)
private UserType userType;
My entities were User and UserType where User have an attribute "userTypeId" as the foreign key.

Related

Jpa repository filter by enum value

public class EmployeeEntity {
#Id
#Column(name = "id")
#GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#Length(min = 2, max = 30)
#Column(name = "name")
private String name;
#Length(min = 2, max = 30)
#Column(name = "last_name")
private String lastName;
#Column(name = "email", nullable = false, unique = true)
#Length(max = 50)
private String email;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "employee_id")
private Set<EmployeeRoleEntity> roles;}
This is my Employee class and as you can see inside Employee, I have a set of EmployeeRoleEntity
public class EmployeeRoleEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#NotNull
#Column(name = "role_name")
#Enumerated(EnumType.STRING)
private RoleEntityEnum role;
#ManyToOne
#JoinColumn(name = "employee_id")
#ToString.Exclude
#EqualsAndHashCode.Exclude
private EmployeeEntity employee;
I was trying to filter my employees depends in their role. I created a method like this on my Jpa repository;
List<EmployeeEntity> findByRoles_RoleContainingIgnoreCase( String role);
But it doesn't work and Im so confused to what to do. How can I solve this problem?
Finally I found the answer;
List<EmployeeEntity> findByRoles_Role( RoleEntityEnum role);
This solved my problem. I thought at first the problem was the method but appearently the problem was parameter.

Java hql query issue

I want to get all the messages of the all user's subscribers with sql or hql. But i don't know how
I want to create the page with messages of all user's subscribers like in twitter or other social networks
I would appreciate any help
Message entity:
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "msg_seq")
#SequenceGenerator(name = "msg_seq", sequenceName = "msg_seq", initialValue = 1, allocationSize = 1)
#Column(name = "id")
private Integer id;
#Column(name = "text")
private String text;
#Column(name = "tag")
private String tag;
#ManyToOne
#JoinColumn(name = "user_id")
private User author;
#Column(name = "header")
private String header;
#Column(name = "like_count")
private Integer likeCount = 0;
#ManyToMany
#JoinTable(
name = "message_likes",
joinColumns = {#JoinColumn(name = "message_id")},
inverseJoinColumns = {#JoinColumn(name = "user_id")}
)
private Set<User> likes;
#OneToOne
#JoinColumn(name = "file_id")
private FileEntity fileEntity;
}
User entity:
public class User {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "usr_seq")
#SequenceGenerator(name = "usr_seq", sequenceName = "usr_seq", initialValue = 1, allocationSize = 1)
#Column(name = "id")
private Long id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "role")
private Role role;
#Column(name = "email")
private String email;
#Column(name = "status")
private Status status;
#Column(name = "subscriber_count")
private Integer subscriberCount = 0;
#Column(name = "subscription_count")
private Integer subscriptionCount = 0;
#OneToOne
#JoinColumn(name = "gender_id")
private Gender gender;
#OneToOne
#JoinColumn(name = "address_id")
private Address address;
#ManyToMany
#JoinTable(
name = "user_subscriptions",
joinColumns = #JoinColumn(name = "channel_id"),
inverseJoinColumns = #JoinColumn(name = "subscriber_id"))
private Set<User> subscribers;
#ManyToMany
#JoinTable(
name = "user_subscriptions",
joinColumns = #JoinColumn(name = "subscriber_id"),
inverseJoinColumns = #JoinColumn(name = "channel_id"))
private Set<User> subscriptions;
#OneToOne
#JoinColumn(name = "file_id")
private FileEntity fileEntity;
}
I tried to write this query for my jpa repository but i couldn't

Error accessing field [private int in Springboot data JPA?

This is entity class , I simply want to save this entity but when I am trying to hit the api I am getting error as given below , I am pretty much sure it is due some mapping issue , any sort of help is appreciated :-
#Entity
#Table(name = "productpurchasedata")
public class Test {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "customerid")
private int customerid;
#Column(name = "name")
private String name;
#Column(name = "mailid")
private String mailid;
#Column(name = "address")
private String address;
#Column(name = "city")
private String city;
#Column(name = "state")
private String state;
#Column(name = "postalcode")
private String postalcode;
#Column(name = "mobileno")
private long mobileno;
#ManyToOne(targetEntity = Test.class, fetch = FetchType.LAZY,optional = false)
#JoinColumns({ #JoinColumn(name = "customerid", referencedColumnName = "customerid", insertable=false, updatable=false) })
private PurchaseDetails purchasedetails;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = Test.class)
#JoinColumn(name = "customerid")
private List<ProductPurchased> productpurchased;
#ManyToOne(targetEntity = Test.class, fetch = FetchType.LAZY,optional = false)
#JoinColumns({ #JoinColumn(name = "customerid", referencedColumnName = "customerid", insertable=false, updatable=false) })
private PaymentHistory paymenthistory;
Error:
"message": "Error accessing field [private int com.bhushan.spring.files.excel.model.Test.customerid] by reflection for persistent property [com.bhushan.spring.files.excel.model.Test#customerid] : com.bhushan.spring.files.excel.model.PaymentHistory#7659b9; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private int com.bhushan.spring.files.excel.model.Test.customerid] by reflection for persistent property [com.bhushan.spring.files.excel.model.Test#customerid] : com.bhushan.spring.files.excel.model.PaymentHistory#7659b9",
You relationship look like wrong I guess. Because one user have many payment history and purchase details not other way round.
Many user doesn't have same same history.
#ManyToOne
private PurchaseDetails purchasedetails;
#ManyToOne
private PaymentHistory paymenthistory

Spring data JPA one to Many / Many to one not inserting/updating details in database

Am doing one small activity of Teach and address relationship for one to many and in address block there will be one to one relationship between country, district, tahasil etc. Whenever am hitting api and to save it it's not updating or inserting Address in address table.
Detail is
#Entity
#Table(name = "teachers")
#PrimaryKeyJoinColumn(name = "user_id")
public class Teacher extends User {
#Size(min = 3, max = 50)
#Column(name = "first_name")
private String firstName;
#Size(min = 3, max = 50)
#Column(name = "middle_name")
private String middleName;
#Size(min = 3, max = 50)
#Column(name = "last_name")
private String lastName;
#OneToMany(fetch = FetchType.LAZY,mappedBy = "teacher")
#JsonManagedReference
private Set<Address> addresses = new HashSet<>(0);
Getter Setter...
}
Then Address Entity
#Entity
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "address_id")
private Long addressId;
#ManyToOne (fetch = FetchType.LAZY)
#JoinColumn(name = "user_id", nullable = false)
#JsonBackReference
private Teacher teacher;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "country_id", referencedColumnName = "country_id")
private Country country;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "state_id", referencedColumnName = "state_id")
private State state;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "district_id", referencedColumnName = "district_id")
private District district;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "tahasil_id", referencedColumnName = "tahasil_id")
private Tahasil tahasil;
#Column(name = "line_one")
private String lineOne;
#Column(name = "line_two")
private String lineTwo;
#Column(name = "landmark")
private String landmark;
#Column(name = "pincode")
private Integer pincode;
public Country getCountry() {
return country;
}
Other Getter Setter
The Country example same to state, district and tahasil
#Entity
#Table(name = "countries", uniqueConstraints = { #UniqueConstraint(columnNames = { "country_name" }) })
public class Country {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "country_id")
private Long countryId;
#NotBlank
#Size(min = 3, max = 50)
#Column(name = "country_name")
private String countryName;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "country")
private Address address;
Getter Setter
Finally in controller am doing like
Optional<Teacher> teacher = teacherRepo.findByUserId(id);
if (!teacher.isPresent())
return ResponseEntity.notFound().build();
teacher.get().setUserId(id);
teacher.get().setFirstName(teacherUpdateForm.getFirstName());
teacher.get().setMiddleName(teacherUpdateForm.getMiddleName());
teacher.get().setLastName(teacherUpdateForm.getLastName());
teacher.get().setAddresses(teacherUpdateForm.getAddresses());
userRepository.save(teacher.get());
Tried so may ways by referring multiple sites and readouts, but still not able to see any insert or update to address table. Please help me to get my mistake.
Regards,
Chetan
You need to cascade the persist of the Teacher entity.
Update the definition of the attribute Address inside the Teacher entity:
#OneToMany(fetch = FetchType.LAZY,mappedBy = "teacher", cascade = CascadeType.ALL)
#JsonManagedReference
private Set<Address> addresses = new HashSet();
You can play with the cascade type value as you want.

SpringData cascade update

This is the first entity:
#Entity
#Table(name = "photographers")
public class Photographer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotNull
#Column(name = "first_name")
private String firstName;
#NotNull
#Size(min = 2, max = 50)
#Column(name = "last_name")
private String lastName;
#Pattern(regexp = "^\\+[0-9]{1,3}/[0-9]{8,10}$")
private String phone;
#NotNull
#OneToOne(optional = false)
#JoinColumn(name = "primary_camera_id", referencedColumnName = "id")
private BasicCamera primaryCamera;
#NotNull
#OneToOne(optional = false)
#JoinColumn(name = "secondary_camera_id", referencedColumnName = "id")
private BasicCamera secondaryCamera;
#OneToMany(mappedBy = "owner")
private Set<Lens> lenses;
#OneToMany(mappedBy = "owner")
private Set<Accessory> accessories;
and this is the other(lenses) :
#Entity
#Table(name = "lenses")
public class Lens {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String make;
#Column(name = "focal_length")
private Integer focalLength;
#Column(name = "max_aperture", precision = 1)
private Double maxAperture;
#Column(name = "compatible_with")
private String compatibleWith;
#ManyToOne
#JoinColumn(name = "owner_id", referencedColumnName = "id")
private Photographer owner;
Firstly i have lenses without owners. Then i want to create a photographer with everything and set its lenses to exiting ones i do this with this code:
for (Lens lens : lensSet) {
lens.setOwner(photographer);
}
photographer.setPrimaryCamera(primaryCamera);
photographer.setSecondaryCamera(secondaryCamera);
photographer.setLenses(lensSet);
and when i save the photographer i want the lenses owner to be set to the created one. I tried cascad.MERGE on the OneToMany realation in the photographer entity but did't work and in the database all lenses owners are still nulls
I figured it out : i need to save the lenses AFTER i save the photographer:
for (Lens lens : lensSet) {
lens.setOwner(photographer);
}
photographer.setPrimaryCamera(primaryCamera);
photographer.setSecondaryCamera(secondaryCamera);
photographer.setLenses(lensSet);
this.photographerRepository.save(photographer);
this.lensRepository.save(lensSet);

Categories