Making one entity to have two association with other same entity - java

I have two entity "user" and "vehicle".
In this user can be a owner or driver of vehicle
If user is owner he will have one to many relation with vehicle that is working fine
But if user is driver he will have one to one relation with vehicle.
I am facing the problem how make two type association between two entity at the same time.
I am posting code below that may help
UserTravelDO
#Entity
#Table(name = "usertraveldo")
public class UserTravelDO implements Serializable {
#GenericGenerator(name = "gen", strategy = "increment")
#GeneratedValue(generator = "gen")
#Id
private int userid;
private String username;
private String password;
private String hint;
private String firstname;
private String middlename;
private String lastname;
private Boolean status;
#JoinColumn(name = "addressid")
#OneToOne(cascade = CascadeType.ALL)
private AddressTravelDO address;
#JoinColumn(name = "roleid")
#ManyToOne(cascade = CascadeType.ALL)
private RoleMasterDO role;
#JsonIgnore
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<VehicleTravelDO> vehicle = new ArrayList<VehicleTravelDO>();
//#JsonIgnore
#OneToOne(mappedBy="driver",fetch = FetchType.EAGER)
private VehicleTravelDO driverofvehicle;
private java.sql.Date modificationdate = new java.sql.Date(new java.util.Date().getTime());
private java.sql.Date creationdate = new java.sql.Date(new java.util.Date().getTime());
private String createdby;
private String modifiedby;
//getters and setters are below
}
VehicleTravelDO
#Entity
#Table(name = "vehicle")
public class VehicleTravelDO implements Serializable {
#GenericGenerator(name = "gen", strategy = "increment")
#GeneratedValue(generator = "gen")
#Id
private int vehicleid;
private String vehicletype;
private String vehiclenumber;
private int totalseats;
private int availableseats;
#JsonIgnore
#JoinColumn(name = "user_id")
#ManyToOne(fetch = FetchType.EAGER)
private UserTravelDO user;
//#JsonIgnore
#OneToOne(fetch = FetchType.EAGER)
private UserTravelDO driver;
//Getters and setters are below
}
After doing this foreign key are getting generated at user and vehicle table.When i insert a vehicle with a user(driver) vehicle id is not getting inserted at the user table but at vehicle table userid(driverid) is getting
inserted.

Related

Is there a way to return user rating of a one book for that user?

I am working on a project, trying to create an AudioBook website. I am stuck on this part and i cant find answers on the internet.
The problem is when i get user, and list of favorite books, each book has list of user rating, from all of the users. And also there is a list of UserRatings that contains all of ratings from that user. I dont want neither.
Basically, is there a way to make it so when i do a search for list of books, every book object contains UserRating(One user rating) from a specific User that is logged in?
#Entity
#Table(name = "user_rating")
public class user_rating {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Integer Id;
#Column
private String rating;
#ManyToOne
#JoinColumn(name = "user_id")
private users user;
#ManyToOne
#JoinColumn(name = "book_id")
private books book;
#Entity
#Table(name = "users")
public class users {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column
private String name;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "date_of_creation")
private java.sql.Date dateOfCreation;
#Column
private String password;
#JsonManagedReference
#ManyToMany
#JoinTable(
name = "favourites",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "book_id", referencedColumnName = "id")
)
private Set<books> favourites = new HashSet<>();
#OneToMany(mappedBy ="user")
private List<user_rating> UserRating = new ArrayList<>();
#Entity
#Table(name = "books")
public class books {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column
private String name;
#Column
private String description;
#Column(name = "date_of_creation")
private java.sql.Date date_of_creation;
#Column
private String text_file;
#JsonBackReference
#ManyToMany(mappedBy = "favourites")
private Set<users> users = new HashSet<>();
#JsonManagedReference
#ManyToMany()
#JoinTable(
name = "book_tags",
joinColumns = #JoinColumn(name = "book_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "tag_id", referencedColumnName = "id")
)
private List<tags> tags = new ArrayList<>();
#OneToOne
#PrimaryKeyJoinColumn
private audio_file audioFile;
#OneToMany(mappedBy = "book")
private List<user_rating> UserRatings = new ArrayList<>();

#JsonIgnoreProperties JPA - Not ignoring properties

I am having a faq entity as below. Here createdBy field is having a manyToOne relationship with the user entity. Below joinColumns shows the association.
In the User entity, i have OneToMany relationship with UserRoles and UsersUnit which is EAGER load for User and not for faq. So i added #JsonIgnoreProperties
for UsersUnit and UsersRole and the corresponding User entity is shown below.
#Entity
#Table(name = "FAQ", catalog="abc")
public class Faq implements Serializable {
public Faq() {
super();
}
#Column(name = "CREATE_DATE")
private Timestamp createDate;
#Where(clause = "DELETE_DATE is null")
#Column(name = "DELETE_DATE")
private Timestamp deleteDate;
#Column(name = "DELETED_BY")
private BigDecimal deletedBy;
#Column(name = "DOC_BLOB", nullable = false)
#JsonIgnore
private byte[] docBlob;
#Column(name = "DOC_NAME", nullable = false, length = 100)
private String docName;
#Id
private BigDecimal id;
#Column(name = "ORDER_BY")
private BigDecimal orderBy;
#Column(name = "UPDATE_DATE")
private Timestamp updateDate;
#Column(name = "UPDATED_BY")
private BigDecimal updatedBy;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumns({
#JoinColumn(name="created_by", referencedColumnName="id")
})
private User faqCreatedBy;
}
User entity:
#Entity
#Table(name = "USERS", catalog="abc")
#JsonInclude(Include.NON_NULL)
public class User extends EntityLog{
private BigDecimal id;
private BigDecimal edipi;
private String firstname;
private String lastname;
private String email;
..///
private Set<UsersRoles> userRoles;
private Set<UsersUnit> usersUnit;
#Id
#Column(name="id")
public BigDecimal getId() {
return id;
}
...///
#Column
#JsonIgnoreProperties({ "faqCreatedBy" })
#OneToMany(fetch = FetchType.EAGER,mappedBy = "user",cascade = {CascadeType.ALL})
#JsonManagedReference
public Set<UsersRoles> getUserRoles() {
return userRoles;
}
...///
#Column
#JsonIgnoreProperties({ "faqCreatedBy" })
#OneToMany(fetch = FetchType.EAGER,mappedBy = "user",cascade = {CascadeType.ALL})
#JsonManagedReference
public Set<UsersUnit> getUsersUnit() {
return usersUnit;
}
////...
}
With this change I am expecting the faq to load with User entity but I am not execting UsersRoles and UsersUnit to load.
But that is not what i see. When faq loads it loads User and UsersRoles and UsersUnit. I am using Spring JPA fyi. Any leads what is wrong ? Appreciate any inputs.

Insert data to multiple tables in spring jpa

I have two tables, user and transaction. Where one user can have many transactions. So, everytime I create new user, they automatically make new transaction and the transaction type is SEND MONEY. But I don't understand how to write it in Spring JPA. Please take a look on my code and help me.
User.java
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
#Column(name = "password")
private String password;
#Column(name = "money")
private int money;
//Getter Setter Constructor
}
Transaction.java
#Entity
#Table(name = "transaction")
public class Transaction {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_trans")
private long id_trans;
#Column(name = "id_user")
private long id_user;
#Column(name = "transaction_date")
private Timestamp transaction_date;
#Column(name = "type") //Default set as "SEND MONEY"
private String type;
#Column(name = "trans_money") //From money in User.class
private int trans_money;
//Getter Setter Constructor
}
I know I should do something in my UserDAO.java, but I still don't know how to send data from body and split(?) it into two object (user and transaction, so I can persist it in UserDAO).
First of all, you have to write the relationship between User and Transaction.
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
#Column(name = "password")
private String password;
#Column(name = "money")
private int money;
#OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private Set<Transaction> transactions = new HashSet<>();
//Getter Setter Constructor
}
#Entity
#Table(name = "transaction")
public class Transaction {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_trans")
private long id_trans;
#Column(name = "id_user")
private long id_user;
#Column(name = "transaction_date")
private Timestamp transaction_date;
#Column(name = "type") //Default set as "SEND MONEY"
private String type;
#Column(name = "trans_money") //From money in User.class
private int trans_money;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(referencedColumnName = "id")
private User user;
//Getter Setter Constructor
}
Then you have to create the JPA repository interface for the User
#Repository
public interface UserRepo extends CrudRepository <User, Long> {
}
Then in a service, you can do the following
#Service
public class UserService {
private UserRepo userRepo;
#Autowired
MealService(UserRepo userRepo){
this.userRepo = userRepo;
}
public void CreateNewUser(){
User user = new User();
// set its values
Transaction transaction = new Transaction();
transaction.setType("SEND MONEY");
// set other values
user.getTransactions().add(transaction);
userRepo.save(user);
}
}
Looking at the #Entity classes mentioned it seems to me that there exists an #ManyToOne association between Transaction and User which is not captured in the entity relationship modeling/mapping.
Please consider modeling that in your Transaction entity as follows,
#Entity
#Table(name = "transaction")
public class Transaction {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_trans")
private long id_trans;
#ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
private User user;
#Column(name = "transaction_date")
private Timestamp transaction_date;
#Column(name = "type") //Default set as "SEND MONEY"
private String type;
#Column(name = "trans_money") //From money in User.class
private int trans_money;
//Getter Setter Constructor
}
Once you do that you can create a JPA repository class for Transaction and User and simply use the save method to do what you want in a transaction after constructing your instances. More on transactions in Spring Data JPA here
public interface TransactionRepository extends JpaRepository<Transaction, Long> {
}

Spring JPA Join two tables without third class

Is there a way to join two tables in Spring JPA without using association class.
I have two MySQL DB tables :
employees(id,.....,department_id)
departments(id,.....)
And I'm searching for a way to join these tables using only my employee and department classes.
Currently, I managed to join two tables but with the third association class.
My current implementation is:
Employee class:
#Entity(name = "Employee")
#Table(name = "employees")
#JsonInclude(Include.NON_NULL)
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#JsonIgnore
#Column(name = "employee_id")
private Long employeeId;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "phone_number")
private String phoneNumber;
#Column(name = "hire_date")
private Double hireDate;
#Column(name = "job_id")
private Long jobId;
#Column(name = "salary")
private Double salary;
#Column(name = "commission_pct")
private Double commissionPct;
#Column(name = "employees")
private Long employees;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id", insertable = false, updatable = false)
#Fetch(FetchMode.JOIN)
private Department department;
}
Department class:
#Entity(name = "Department")
#Table(name = "departments")
#JsonInclude(Include.NON_NULL)
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "department_name")
private String departmentName;
#Column(name = "department_id")
private long departmentId;
#Column(name = "manager_id")
private Double managerId;
#Column(name = "location_id")
private Double locationId;
}
Association class:
public class DeptEmpDto {
private long departmentId;
private String departmentName;
private Double managerId;
private Double locationId;
private long employeeId;
private String firstName;
private String lastName;
private String phoneNumber;
private Double hireDate;
private Long jobId;
private Double salary;
private Double commissionPct;
}
Repository:
public interface IEmployeeRepository extends JpaRepository<Employee, Long> {
#Query("SELECT new com.concretepage.entity.DeptEmpDto(d.departmentId,d.departmentName,d.managerId,d.locationId,e.employeeId,e.firstName,e.lastName,e.phoneNumber,e.hireDate,e.jobId,e.salary,e.commissionPct FROM Employee e INNER JOIN Department d ON d.id = e.jobId")
List<DeptEmpDto> fetchEmpDeptDataInnerJoin();
You can use it in Employee class
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(
name = "DeptEmp",
joinColumns = #JoinColumn(name = "emp_id",referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "dep_id",referencedColumnName = "id")
)
private Set<Departments> departments = new HashSet<>();
Look at this about JPA
Logically an employee can't work in two departements so your relationship is correct
But you can do that with a #ManyToMany annotation.

jpa entity mapping couple tables

I had entity for JSON parsing
#Entity
public class Product{
private int productId;
private String productName;
private BigDecimal productPrice;
private int productVendorId;
private String productVendorName;
private int productCategoryId;
private String productCategoryName;
//getters setters here
created 3 tables in dataBase:
products (product_id, product_name,product_price, product_vendor_id), product_category_id);
vendors(vendor_id, vendor_name); categories (category_id, category_name);
in 1st table product_vendor_id fk -> vendor_id pk in vendors and product_category_id fk -> category_id pk in categories
i tried something like this:
#Entity
#Table(name = "products, schema = "market")
public class Product
#Id
#Column(updatable = false, nullable = false, name = "product_id")
private int Id;
#Column(name = "product_name")
private String productName;
#Column(name = "product_price")
private BigDecimal productPrice;
#Column(name = "product_vendor_id")
private int productVendorId;
#Columnt(table = "vendors", name = "vendor_name")
private String vendor_name;
#Column(name = "product_category_id")
private int productCategoryId;
#Column(table = "categories", name = "category_name")
private String productCategorName;
//getters setters here
received alot of errors: like i have not category_name column in products table etc. this error i received when used
#Table(name = "products", schema = "market" )
#SecondaryTables({#SecondaryTable(name = "vendors", schema = "market"),
#SecondaryTable(name = "categories", schema = "market")})
#JsonIgnoreProperties(ignoreUnknown = true)
public class Product {
....
#JoinColumn(name = "product_vendor_id", referencedColumnName = "vendor_id")
private int productVendorID;
#JoinColumn(table = "vendors", name = "vendor_name")
private String productVendorName;
#JoinColumn(name = "product_category_id", referencedColumnName =
"product_category_id")
private int productCategoryID;
#JoinColumn(table = "categories", name = "category_name")
private String productCategoryName;
exception:
Caused by: org.postgresql.util.PSQLException: ERROR: column
product0_1_.product_id doesn't exist
Hint: There may have been a link to the "product0_.product_id" column
Position: 705
how can i map this entity on 3 tables?
upd: i don't want separate this entity, i need this for deserialize my json object too, just want reuse this entity on different operations.
example of json
{"productID":"1111111","productName":"Cool product","productPrice":"99.99","productVendorName":"Some store","productVendorID":"1337","productCategoryName":"Food","productCategoryID":"1"}
Since there are 3 separate tables, you would want to create three separate entity classes.
Also I'm assuming vendors and category tables will have one to many relation to product.
Try below code:
Product:
#Entity
public class Product {
#Id
private int productId;
private String productName;
private BigDecimal productPrice;
private String productVendorName;
private String productCategoryName;
#ManyToOne
#JoinColumn(name = "productCategoryId")
private Category category;
#ManyToOne
#JoinColumn(name = "productVendorId")
private Vendors vendor;
}
Category:
#Entity
public class Category {
#Id
private Integer categoryId;
private String categoryName;
#OneToMany(mappedBy = "category", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
#NotEmpty
private List<Product> products = new ArrayList<>();
}
Vendors:
#Entity
public class Vendors {
#Id
private int vendorId;
private String vendorName;
#OneToMany(mappedBy = "vendor", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
#NotEmpty
private List<Product> products = new ArrayList<>();
}
Though, I would recommend using above approach, if you still want to have single entity class and 3 separate table with redudant data then use below:
#Entity
#SecondaryTables({ #SecondaryTable(name = "vendors"), #SecondaryTable(name = "categories") })
public class Product {
#Id
private int productId;
private String productName;
private BigDecimal productPrice;
private String productVendorName;
private String productCategoryName;
#Column(table = "categories")
private Integer categoryId;
#Column(table = "categories")
private String categoryName;
#Column(table = "vendors")
private int vendorId;
#Column(table = "vendors")
private String vendorName;
}
The id column of the main table will be present in all the 3 tables and used for joining them.
Sorry for poor wording of the question, just didn't know how to explane what i wanted.
All what i need just add #transient annotations for fields which i don't have in products table, and separate it like accepted answer was suggested.
#Entity
#Table(name = "products", schema = "store" )
#JsonIgnoreProperties(ignoreUnknown = true)
public class Product {
#Id
#Column(updatable = false, nullable = false, name = "product_id")
private int productId;
#Column(name = "product_name")
private String productName;
#Column(name = "product_price")
private BigDecimal productPrice;
#Transient
private String productVendorName;
#Transient
private String productCategoryName;
#Transient
private int vendorId;
#Transient
private int categoryId;
#ManyToOne
#JoinColumn(name = "product_category_id")
private Category category;
#ManyToOne
#JoinColumn(name = "product_vendor_id")
private Vendor vendor;
}
for vendors table entity
#Entity
#Table(name = "vendors", schema = "store")
public class Vendor {
#Id
#Column(name = "vendor_id")
private int vendorId;
#Column(name = "vendor_name")
private String vendorName;
#OneToMany(mappedBy = "vendor", cascade = CascadeType.ALL, fetch = FetchType.LAZY,
orphanRemoval = true)
#NotNull
private List<Product> products = new ArrayList<>();
}
and for categories
#Entity
#Table(name = "categories", schema = "store")
public class Category {
#Id
#Column(name = "category_id")
private Integer categoryId;
#Column(name = "category_name")
private String categoryName;
#OneToMany(mappedBy = "category", cascade = CascadeType.ALL, fetch = FetchType.LAZY,
orphanRemoval = true)
#NotNull
private List<Product> products = new ArrayList<>();
}
Wanted to leave here full answer on my question, maybe someone will need it later
Just check some problems with toString. Use it only in Product.class and better make 2 versions for print json and jpa.

Categories

Resources