Spring boot table to show list of pets by owner id - spring-boot

I'm making a small school project Spring Boot web application. Right now I have made CRUD for Owners table in the database, what I'm trying to do next is when I click button "pets" I want to be able to show only those pets that has the same "owner_id". I guess I should receive "owner_id" from the button that was pressed. How can I make that it works the way it should work? Now when I press button "pets" it shows all list of the pets.
Owner class:
#Entity
#Table(name = "owners")
public class Owner {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name", nullable = false)
private String firstName;
#Column(name = "last_name", nullable = false)
private String lastName;
#Column(name = "email", nullable = false)
private String email;
#OneToMany(targetEntity = Pet.class,cascade = CascadeType.ALL)
#JoinColumn(name = "owner_id", referencedColumnName = "id")
private List<Pet> pets;
public Owner() {
}
public Owner(String firstName, String lastName, String email) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
}
Pet class:
#Table(name = "pets")
public class Pet {
#Id
private Long id;
private String name;
private String breed;
private int age;
private double weight;
public Pet() {
}
public Pet(String name, String breed, int age, double weight) {
super();
this.name = name;
this.breed = breed;
this.age = age;
this.weight = weight;
}
}
Controller method for list of pets:
#GetMapping("/owner_pets")
public String getAllPetsByOwnerId(Model model) {
model.addAttribute("pets", petService.getAllPetsByOwnerId());
return "owner_pets";
}
Here is the code written so far but it only shows list of all pets

I saw your service method for PerService. I do not see any ownerId being passed to findByOwnerId method. That might be the reason why you are getting all pets in response. What you should ideally do is
package com.veterinary.Veterinary_system.service;
import java.util.List;
import com.veterinary.Veterinary_system.entity.Pet;
public interface PetService {
//Repository declaration
List < Pet > findByOwnerId(Long ownerId){
return petRepository.findByOwnerId(ownerId);
}
Pet savePet(Pet pet);
}

Related

how to add object with fk to table in jparepository

i had scheme of user parking and detail parking.
user can park many times (one to many)
im trying to add detail parking object to my db, but i dont have idea how to add the fk from the user in the row of the table, its gave me null there.
(ignore from the logic of the model, i just want to understood the logic how can i the object with fk of ther entity)
this is my code:
#PostMapping("/parking")
public String saveCarParking(#ModelAttribute("user") parkingUsers parkingUsers) {
// parkingUsers[id, firstName, lastName, license]
parkingUsers p = new parkingUsers("jhon", "nash", "248651355");
parkingUsersService.saveParkingUser(p);
// parkingDetails[id, entryDate, entryTime, exitDate, exitTime, user_id(FK)]
parkingDetails d = new parkingDetails(LocalDate.now(), null, LocalDate.now(), null);
parkingDetailsService.saveParkingUser(d);
//how i connect parkingDetails object with fk of parkingUsers?
//it adding now row of parkingDetails but without the fk of user
return "redirect:/parkingList";
}
parking user entity:
#Entity
#Table(name ="users")
public class parkingUsers {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "license")
private String license;
#OneToMany(mappedBy = "parkingUsers", cascade = CascadeType.ALL, orphanRemoval = true)
private List<parkingDetails> parkingDetails = new ArrayList<parkingDetails>();
public parkingUsers() {
}
public parkingUsers(String firstName, String lastName, String license) {
this.firstName = firstName;
this.lastName = lastName;
this.license = license;
}
//setter gettrs and tostring...
entity class of details parking
#Entity
#Table(name ="details")
public class parkingDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "entry_date")
private LocalDate entryDate;
#Column(name = "entry_time")
private LocalDateTime entryTime;
#Column(name = "exit_date")
private LocalDate exitDate;
#Column(name = "exit_time")
private LocalDateTime exitTime;
#ManyToOne
#JoinColumn(name="user_id")
private parkingUsers parkingUsers;
public parkingDetails() {}
public parkingDetails(LocalDate entryDate, LocalDateTime entryTime, LocalDate exitDate, LocalDateTime exitTime) {
this.entryDate = entryDate;
this.entryTime = entryTime;
this.exitDate = exitDate;
this.exitTime = exitTime;
}
//test
// public parkingDetails(LocalDate entryDate, LocalDateTime entryTime, LocalDate exitDate, LocalDateTime exitTime, int user_id ) {
// this.entryDate = entryDate;
// this.entryTime = entryTime;
// this.exitDate = exitDate;
// this.exitTime = exitTime;
// this.parkingUsers.setId(user_id);
// }
//setter gettrs and tostring...
In the ParkingDetails entity, you can have a setter for "parkingUsers" variable to set user object.
In your REST api's saveCarParking() method, before calling "parkingDetailsService.saveParkingUser(d);" you can pass the user object to ParkingDetails using setter created in ParkingDetails.
This should work. No need to explicitly extract the user_id from user's object to pass into ParkingDetails.
Adding one more parameter of type ‘parkingUsers‘ in the constructor of ‘ ParkingDetails’ to initialize user in parking class will also work.
(Apart, it is a good practice to start the class name with a capital letter e.g. instead of having class name as parkingDetails, it should be ParkingDetails.)

JPA: How can I read particular fields of an Entity?

I use Spring JPA ( Hibernate ) and have bunch of entities which are mapped onto tables.
When I use an entity to write I need many fields in it (see an example below). But when I read, I wanna sometimes read only particular fields like first/last name. How can I perform it using Spring data JPA ? ( because due to CrudRepository nature it returns the whole entity)
#Entity
#Table(name="PERSON")
#AttributeOverride(name = "id", column = #Column(name = "ID_PERSON"))
public class Person extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name="LAST_NAME", length = 100, nullable = false)
private String lastName;
#Column(name="FIRST_NAME", length = 50, nullable = false)
private String firstName;
#Column(name="MIDDLE_NAME", length = 50)
private String middleName;
#Column(name="BIRTHDAY", nullable = false)
#Temporal(value = TemporalType.DATE)
private Date birthday;
#ManyToOne(fetch = FetchType.LAZY, optional = true)
#JoinColumn(name = "ID_SEX")
private Sex sex;
public Person() {
super();
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Sex getSex() {
return sex;
}
public void setSex(Sex sex) {
this.sex = sex;
}
}
There are various possibilities.
With Spring Data JPA you can use projection (that's the name when you only select certain fields/columns of an entity/table).
You can return List of Object[] or a DTO or an Interface.
For example with interface it looks like this:
interface NamesOnly {
String getFirstname();
String getLastname();
}
interface PersonRepository extends Repository<Person, UUID> {
Collection<NamesOnly> findByLastname(String lastname);
}
As you can see the return value most not be of type Person.
Please check out the documentation:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
I was faced with a similar issue and I resorted to this:
Let's say you have your entity FooEntity related to repository FooRepository
To only get certain fields, let's say firstName and lastName using key I had to create a custom query in the FooRepository
In this manner
#Query("select new FooEntity(f.firstName, f.lastName) from FooEntity f where f.key = :key")
Optional<FooEntity> findCustomByKey(#Param("key") BigInteger key);
You also have to ensure that the FooEntity has the constructor accepting the values that you only want to be set or returned in this manner:
public FooEntity(String firstName, String lastName){
// Ensure the constructor is not called with null values
notNull(firstName, "Method called with null parameter (firstName)");
notNull(lastName, "Method called with null parameter (lastName)");
this.firstName = firstName;
this.lastName = lastName;
}
Please the full code below:
public class FooEntity implements Serializable {
#Id
#Column(name = "key")
private BigInteger key;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "birth_date")
private Date birthDate;
#Column(name = "hash")
private String hash;
public FooEntity(String firstName, String lastName){
// Ensure the constructor is not called with null values
notNull(firstName, "Method called with null parameter (firstName)");
notNull(lastName, "Method called with null parameter (lastName)");
this.firstName = firstName;
this.lastName = lastName;
}
// Getters and Setters
}
public interface FooRepository extends JpaRepository<FooEntity, BigInteger>{
#Query("select new FooEntity(f.firstName, f.lastName) from FooEntity f where f.key = :key")
Optional<FooEntity> findCustomById(#Param("key") BigInteger key); // This one only returns two set fields firstName and LastName and the rest as nulls
Optional<FooEntity> findById(BigInteger key) // This one returns all the fields
}

Null Foreign Key (Springboot, Hibernate, Postman)

I am using Springboot with Hibernate and I would like to save a new “post” using a POST request to my database. One thing that I would like to highlight is that I am using the dependency “spring-boot-starter-data-rest”.
Schema of the database (MySQL):
Class User:
#Entity
#Table(name="user")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id", nullable = false)
public int id;
#OneToMany(mappedBy = "user_id_fk")
public Set<Post> posts;
#Column(name="email")
private String email;
#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="create_time")
protected Date createTime;
#Column(name="type")
private String accountType;
public User() {
this.createTime = new java.util.Date();
}
public User(String email, String username, String password, String firstName, String lastName, Date createTime, String accountType) {
this.email = email;
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.createTime = createTime;
this.accountType = accountType;
this.createTime = new java.util.Date();
}
public User(int id, String email, String username, String password, String firstName, String lastName, Date createTime, String accountType) {
this.id = id;
this.email = email;
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.createTime = createTime;
this.accountType = accountType;
this.createTime = new java.util.Date();
}
Plus the Getters & Setters & toString().
Class Post:
#Entity
#Table(name="post")
public class Post implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
public int id;
#ManyToOne(optional = false)
#JoinColumn(name = "user_id_fk", nullable = false)
public User user_id_fk;
#Column(name="comment")
private String comment;
#Column(name="likes")
private int likes;
#Column(name="dislike")
private int dislike;
#Column(name="create_time")
protected Date createTime;
public Post() {
this.createTime = new java.util.Date();
}
public Post(String comment, int likes, int dislike, User user_id_fk) {
this.user_id_fk = user_id_fk;
this.comment = comment;
this.likes = likes;
this.dislike = dislike;
this.createTime = new java.util.Date();
}
public Post(int id, User user_id_fk, String comment, int likes, int dislike) {
this.id = id;
this.user_id_fk = user_id_fk;
this.comment = comment;
this.likes = likes;
this.dislike = dislike;
this.createTime = new java.util.Date();
}
Plus the Getters & Setters & toString().
Post request (I'm using Postman to send the request):
{
"comment" : "This is a comment",
"likes" : 123,
"dislike" : 1,
"user_id_fk" :
[
{
"id" : 1
}
]
}
In the request at the "user_id_fk" I tried with [ {"id" : 1 } ] and with { "id" : 1 } but the result was the same.
Issue:
When I am executing exactly the same code from my controller everything works are excepted. Bear in mind that I am using the dependency “spring-boot-starter-data-rest”.
Also, when I am executing the code without the “optional = false” and “nullable = false” is inserting the data into the database but the “user_id_fk” is null :(.
The error that I am getting:
not-null property references a null or transient value : com.citizen.citizen.entity.Post.user_id_fk;
nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.citizen.citizen.entity.Post.user_id_fk]
That means that the foreign key ("user_id_fk") is null but should not be null.
Any help will be greatly appreciated.
I just remove the dependency "spring-boot-starter-data-rest" and I solved the issue by creating my custom rest and everything works. Kisses!
According to this article, you should make user_id_fk nullable and then:
Send POST to create User
Send second POST to create Post
Send PUT to create a relation between the two.
This article states the same.
And the documentation only mentions handling associations via association links.

How to fix jpa one to many

Need to fetch data from one table to another.I performed jpa one to many mapping. But id cannot fetched. Where is my mistake?
I have tried mapping using one to many and many to one concepts but can't able to fetch data from one table to another
User.java
#Entity
#Table(name = "users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "User_ID")
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
private String firstName;
private String lastName;
private Long phoneNumber;
#NotNull(message="Password is compulsory")
#Email(message = "Email is invalid")
private String email;
private String password;
#OneToMany(mappedBy="user", cascade = CascadeType.ALL)
Set<Data> data = new HashSet<Data>();
public Set<Data> getData() {
return data;
}
public void setData(Set<Data> data) {
this.data = data;
}
public User() {
super();
}
Data.java
#Entity
#Table(name = "data")
public class Data implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "DataID")
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
#ManyToOne(fetch = FetchType.EAGER,cascade= CascadeType.ALL)
#JoinColumn(name = "User_ID")
private User user;
public Data() {
super();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
DataController.java
#PostMapping("/data/{userId}")
public Data createData(
#PathVariable(value= "userId") String userId,
#Valid #RequestBody Data data) {
return userRepository.findById(userId).map(user -> {
data.setUser(user);
return dataRepository.save(data);
}).orElseThrow(() -> new ResourceNotFoundException("userId" + userId +
"not found"));
}
Results in no error but can't able to fetch user id

Heroku spring-jpa UniqueConstraint

I met a problem: in my course project I use spring-jpa and create UserEntity with two unique fields. On my local machine all works perfectly well (creates unique constraints in db), but on heroku unique constraints doesn't creates.
I use java9 + spring-jpa.
import javax.persistence.*;
#Entity(name = "UserEntity")
#Table(name = "user_entity", uniqueConstraints = {
#UniqueConstraint(columnNames = {"nickname"}, name = "nickname_constraint"),
#UniqueConstraint(columnNames = {"email"}, name = "email_constraint")
})
public class UserEntity {
private Integer id;
private String nickname;
private String email;
private String passwordHash;
private String avatarPath;
private GameResults gameResults;
public UserEntity() {
}
public UserEntity(String nickname, String email, String password) {
this.nickname = nickname;
this.email = email;
this.passwordHash = password;
}
public UserEntity(String nickname, String password) {
this.nickname = nickname;
this.passwordHash = password;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
#Column(name = "nickname")
public String getNickname() {
return this.nickname;
}
#Column(name = "avatar_path")
public String getAvatarPath() {
return avatarPath;
}
#Column(name = "email")
public String getEmail() {
return email;
}
#Column(name = "password_hash")
public String getPasswordHash() {
return passwordHash;
}
#OneToOne(fetch = FetchType.LAZY)
public GameResults getGameResults() {
return gameResults;
}
// setters ommited
}
Thank you jusermar10!
Really, the problem was that i have deployed application with incorrect jpa entity first time. After redeploying fixed version of application there weren't necessary constraints in the postgres. So dropping db and restarting all dynos helped me.

Resources