Error accessing field [private int in Springboot data JPA? - java

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

Related

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.

Spring Data JPA/Hibernate LazyInitializationException

I am new to hibernate/spring data JPA and occuring some problems when dealing with Foreign Keys.
I have the two table:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private String email;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String role;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "job_id", referencedColumnName = "id")
private Job job;
}
#Entity
public class Job{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String name;
#OneToMany(
mappedBy = "job",
cascade = CascadeType.PERSIST,
fetch = FetchType.EAGER
)
private Set<User> users = new HashSet<>();
}
I am trying to save one Job (job.Id) at the Users table. But if I am trying to peform a get(repository.getOne(id)) (via ...extends JPARepository<User,Long> I am getting the following error:
org.hibernate.LazyInitializationException: could not initialize proxy [backend.entity.User#193] - no Session
Does anyone has a Tip how to fix it? I have read a lot on stackoverflow, but could not find out how to fix that.

Spring Cannot add foreign key constraint #ManyToOne

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.

How to Query referenced tables in JPA Spring

I have 4 models:
Blueprint, that describes a single type of Item:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="name")
private String name;
#ElementCollection
#CollectionTable(name = "BLUEPRINT_TAG", joinColumns = #JoinColumn(name = "blueprint"))
private List<String> tags;
#OneToMany(mappedBy = "blueprint", cascade = CascadeType.ALL, orphanRemoval = true)
private List<BlueprintProperty> properties;
#OneToMany(mappedBy = "blueprint", cascade = CascadeType.ALL, orphanRemoval = true)
#JsonIgnore
private List<Item> items;
#Column(name = "width")
private Float width;
#Column(name = "height")
private Float height;
#Column(name = "imagePath")
private String imagePath;
#Column(name = "zPosition")
private long zPosition;
BlueprintProperty, that describes what information can be entered for each type of Item.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "blueprint")
#JsonIgnore
private Blueprint blueprint;
#Column(name = "name")
private String name;
#Enumerated(EnumType.STRING)
private PropertyType type;
#Column(name = "data")
#Convert(converter = JpaJsonConverter.class)
private ObjectNode data;
#OneToMany(mappedBy = "property", cascade = CascadeType.ALL, orphanRemoval = true)
#JsonIgnore
private List<ItemProperty> itemProperties;
Then there's Item:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "parent")
//#Nullable
private Item parent;
#Column(name = "pos_x")
private Float posX;
#Column(name = "pos_y")
private Float posY;
#Column(name = "transformation")
private String transformation;
#ManyToOne
#JoinColumn(name = "blueprint")
private Blueprint blueprint;
#OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
#JsonIgnore
private List<Item> children;
#OneToMany(mappedBy = "item", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ItemProperty> properties;
And finally, ItemProperty, that holds foreign keys referencing Item the specific property belongs to, and BlueprintProperty it's describing:
#Id
#ManyToOne
#JoinColumn(name = "item")
#JsonIgnore
private Item item;
#Id
#ManyToOne
#JoinColumn(name = "property")
#JsonIgnore
private BlueprintProperty property;
#Column(name = "value")
private String value;
Now, I'm not exactly happy with this setup, but that's what I have to work with and unless completely necessary I shouldn't change anything. What I'm trying to do is create a Query that takes a number of Item properties and returns all Items which properties match the query.
Using Query by example sounded promising, but I found out that only SingularAttribute properties can currently be used for property matching.. So that killed that approach, and I don't think I can use native query, because a certain Item can have N properties, and you should be able to enter a query that searches by a single property, up to N properties.
Can someone suggest a way to perform the search I need and get a List of Items matching whose properties matched those entered as a result?

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