I have two tables CustomerDetails and Product, I want to fetch customerid from customer table and add it to #joincolumn(order_id) column in same CustomerDetails table.
CustomerDetails.java
#Entity
#Table(name = "CustomerDetails")
public class CustomerDetails {
#Id
#GeneratedValue
#Column(name="CUSTOMER_ID")
private Long custid;
#Column(name="CUSTOMER_NAME")
private String customerName;
#Column(name="EMAIL")
private String email;
#Column(name="ADDRESS")
private String address;
#Column(name="PHONENO")
private String phoneno;
public CustomerDetails() {
}
#Override
public String toString() {
return "CustomerDetails [custid=" + custid + ", customername=" + customerName + ", email=" + email
+ ", address=" + address + ", phoneno=" + phoneno + "]";
}
public CustomerDetails(String customername, String email, String address, String phoneno) {
super();
this.customerName = customername;
this.email = email;
this.address = address;
this.phoneno = phoneno;
}
public Long getCustid() {
return custid;
}
public void setCustid(Long custid) {
this.custid = custid;
}
public String getName() {
return customerName;
}
public void setName(String name) {
this.customerName = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return address;
}
public void setPassword(String password) {
this.address = password;
}
public String getPhoneno() {
return phoneno;
}
public void setPhoneno(String phoneno) {
this.phoneno = phoneno;
}
}
Product.java
#Entity
#Table(name="Product")
public class Product {
#Id
#GeneratedValue
#Column(name="PRODUCT_ID")
private Long productId;
#Column(name="PRODUCT_NAME")
private String productName;
#Column(name="PRODUCT_BRAND")
private String productBrand;
#Column(name="PRODUCT_PRICE")
private double productPrice;
#OneToOne
private CustomerDetails cd;
public Product(Long productId, String productName, String productBrand, double productPrice, CustomerDetails cd) {
super();
this.productId = productId;
this.productName = productName;
this.productBrand = productBrand;
this.productPrice = productPrice;
this.cd = cd;
}
public Product(String productName, String productType, double productPrice) {
super();
this.productName = productName;
this.productBrand = productType;
this.productPrice = productPrice;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductBrand() {
return productBrand;
}
public void setProductBrand(String productType) {
this.productBrand = productType;
}
public double getProductPrice() {
return productPrice;
}
public void setProductPrice(double productPrice) {
this.productPrice = productPrice;
}
public CustomerDetails getCd() {
return cd;
}
public void setCd(CustomerDetails cd) {
this.cd = cd;
}
public Product() {
//super();
}
#Override
public String toString() {
return "Product [productId=" + productId + ", productName=" + productName + ", productType=" + productBrand
+ ", productPrice=" + productPrice + "]";
}
}
CustomerDetails repository
#Repository
public interface CdRepo extends JpaRepository<CustomerDetails, Long>
{
}
Product repository
#Repository
public interface ProductRepo extends JpaRepository<Product, Long>
{
}
CustomerService
#Service
#Transactional
public class CustomerService {
private final CdRepo cdRepo;
#Autowired
public CustomerService(CdRepo cdRepo) {
this.cdRepo = cdRepo;
}
public void saveCustomer(CustomerDetails cd)
{
cdRepo.save(cd);
}
}
controller
#RequestMapping(value = {"/addCustomerDetails"}, method = RequestMethod.POST)
public ModelAndView addCustomerDetails(CustomerDetails cd)
{
customerService.saveCustomer(cd);
System.out.println(cd.getCustid());
ModelAndView model = new ModelAndView();
model.setViewName("homepage");
return model;
}
In controller using getCustid() I'm getting current customer's id now I want to insert that id into #joinColumn(order_id)
If I've understood correctly, you want to assign a product to a user (e.g Customer).
For a #OneToOne relation you don't need private CustomerDetails cd; in product class. Although I don't know why are you implementing such thing in that way at all!
Generally If you want to assign two things together, let's say you want to assign a product to a user so that the product would be for that user, you should find the product obj from repository or any where (both product and user must have an id generated by db) and then assign it to user.product.
product service
#Service
public class ProductService {
#Autowired
private ProductRepo productRepository;
public Optional<Product> findProductById(Long id) {
return this.productRepository.findByProductId(id);
}
}
customer service
#Service
#Transactional
public class CustomerService {
private final CdRepo cdRepo;
#Autowired
public CustomerService(CdRepo cdRepo) {
this.cdRepo = cdRepo;
}
public CustomerDetails saveCustomer(CustomerDetails cd, Long productId) {
CustomerDetails dbCustomer = customerService.saveCustomer(cd);
// I'm getting the id from path variable, change it if you have other logics
Optional<Product> dbProduct = this.productService.findProductById(productId);
// I don't know how you handle run time errors so I can't write it, don't
// forget to check the dbProduct in case it didn't exist :)
// In case you did not created getters and setters in CustomerDetails,
// use dbCustomer.product = dbProduct.get();
dbCustomer.setProduct(dbProduct.get());
// update our customer using JPA, after customer update JPA handles everything
return this.cdRepo.save(dbCustomer);
}
}
controller
#RequestMapping(value = {"/addCustomerDetails/{productId}"}, method = RequestMethod.POST)
public ModelAndView addCustomerDetails(CustomerDetails cd, #PathVariable Long productId )
{
CustomerDetails dbCustomer = this.customerService.saveCustomer(cd, productId);
// Use the dbCustomer in your logic ...
ModelAndView model = new ModelAndView();
model.setViewName("homepage");
return model;
}
Write getters and setters in each entity or use Lombok annotation #Data.
Usually when I want to deploy an ecommerce with user and product. I use user, cart, product model.
The problem with the code above is that if you assign that product to a user, it's ONLY for that user. if other users want the same product you have to create all of those products for them. Solution to that would be using product as a series or a model.
Imagine a situation that you want to create a website to sell coffee packages. you only have two type of package to sell. you can create an entity like product for those packages with a quantity for each. Then create a #OneToMany relationship in your cart model to products. It will create a join table to store any possible product id there with cart id. After that, create a #ManyToOne relationship in your cart entity and #OneToMany in your user entity. Now each cart is only for a specific user and not the products.
Some Friendly Advice:
Don't populate your controller with logic. Let service layer handle it.
For each entity, create a package with the name of the entity instead and create 3 classes; the entity itself, response POJO and request POJO.
Use getters and setters for your entites. You can use lombok for that matter. It will handle the situation by generating them.
Use convertor components to create and convert requested entity to the entity itself and also convert entity to response entity.
Avoid interacting with Data base as much as you can. hold the object in a variable like dbCustomer for doing operations.
Related
I would like to know if there is any way to use a parameter from a function I pass to a repository can be used in the #Query.
I would like to sort users by gaming platform so I added the following function to my UserRepository:
#Repository
public interface UserRepository extends CrudRepository<DbUser, Integer> {
#Query("SELECT * from users WHERE platform = *****parameter here***** ")
public List<DbUser> findAllByPlatform(String platform);
}
Does anybody know if this is possible? If so, how? If not, is there a clean workaround? Thanks in advance.
EDIT: My DbUser class:
#Entity
#Table(name = "users")
public class DbUser {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="user_id")
private int UserId;
#Column(name="user_name")
private String UserName;
#Column(name="email_address")
private String EmailAddress;
#Column(name="password_hash")
private int PasswordHash;
#Column(name="platform")
private String Platform;
#Column(name="platformid")
private String PlatformID;
#Convert(converter = StringListConvertor.class)
private ArrayList<String> Wishlist;
public DbUser(String userName, String emailAddress, int passwordHash, String platform, String platformID, String newWishlistItem){
UserName = userName;
EmailAddress = emailAddress;
PasswordHash = passwordHash;
Platform = platform;
PlatformID = platformID;
Wishlist.add(newWishlistItem);
}
public DbUser() {
}
public int getUserId() {
return UserId;
}
public void setUserId(int userId) {
UserId = userId;
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getEmailAddress() {
return EmailAddress;
}
public void setEmailAddress(String emailAddress) {
EmailAddress = emailAddress;
}
public int getPasswordHash() {
return PasswordHash;
}
public void setPasswordHash(int passwordHash) {
PasswordHash = passwordHash;
}
public String getPlatform() {
return Platform;
}
public void setPlatform(String platform) {
Platform = platform;
}
public String getPlatformID() {
return PlatformID;
}
public void setPlatformID(String platformID) {
PlatformID = platformID;
}
public ArrayList<String> getWishlist() {
return Wishlist;
}
public void setWishlist(ArrayList<String> wishlist) {
Wishlist = wishlist;
}
}
If you're using Spring data, annotate parameter with #Param and supply variable name to be used in query:
#Query("SELECT * from users WHERE platform = :pltfrm")
public List<DbUser> findAllByPlatform(#Param("pltfrm") String platform);
You can do something like that
#Query("SELECT * from users WHERE platform = %?1")
spring data jpa documentation
I created a table of "User" which is perfectly created by hibernate, no problem on this one. The problem is on my second model (an entity called "Character") which is a model with a #ManyToOne relation, I don't know why but hibernate can't create this second table.
My server is a MySql instance with AWS RDS. The first table is created by hibernate but not the second.
#Entity
public class Character {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#ManyToOne
private User joueur;
private String pseudo;
private Integer points;
public Character() {
super();
}
public Character(User joueur) {
// appel a l'autre constructeur
this(joueur, null, null);
}
public Character(User joueur, String pseudo,Integer points) {
super();
this.joueur = joueur;
this.pseudo = pseudo;
this.points = points;
}
public Integer getId() {
return id;
}
public String getPseudo() {
return pseudo;
}
public void setPseudo(String pseudo) {
this.pseudo = pseudo;
}
public Integer getPoints() {
return points;
}
public void setPoints(Integer points) {
this.points = points;
}
public User getJoueur() {
return joueur;
}
}
#Entity // This tells Hibernate to make a table out of this class
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String username;
private String password;
#OneToMany(mappedBy = "joueur")
#OrderBy("id ASC")
private List<Character> personnages;
private String league;
private Integer points;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Character> getPersonnages() {
return personnages;
}
public void setPersonnages(List<Character> personnages) {
this.personnages = personnages;
}
public String getLeague() {
return league;
}
public void setLeague(String league) {
this.league = league;
}
public Integer getPoints() {
return points;
}
public void setPoints(Integer points) {
this.points = points;
}
}
#Controller
#RequestMapping(path="/init")
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#Autowired
private CharacterRepository characterRepository;
#GetMapping(path="/add") // Map ONLY GET Requests
public String addNewUser () {
User joueur = new User();
joueur.setUsername("testUser");
joueur.setPassword("password");
joueur.setLeague("Bronze");
joueur.setPoints(10000);
userRepository.save(joueur);
Character perso = new Character(joueur,"testPerso1",1000);
characterRepository.save(perso);
return "";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<User> getAllUsers() {
// This returns a JSON or XML with the users
return userRepository.findAll();
}
}
I have this error :
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'character add constraint Kdf2yvyvitaqt2u7de3ywfjcv foreign key (joueur_id) refe' at line 1
Ok I found the solution ... JPA annotation fordid the name of the table 'Character", just change the name of the table and it will work perfectly, stupid JPA ...
I have three entity classes, I have written the query which includes join of two tables.
Table: ExpensesCategories
#Entity
#Table(name = "ExpensesCategories")
public class ExpensesCategories {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id", unique = true)
private int categoryId;
#NotNull
private String categoryName;
#NotNull
private String categoryCodeInBankStats;
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryCodeInBankStats() {
return categoryCodeInBankStats;
}
public void setCategoryCodeInBankStats(String categoryCodeInBankStats) {
this.categoryCodeInBankStats = categoryCodeInBankStats;
}
}
Table: Transactions
#Entity
#Table(name = "TransactionHistory")
public class TransactionHistory {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Temporal(TemporalType.DATE)
private Date dateOfTransaction;
private String transactionType;
private String refNo;
private Date valueDate;
private double withdrawalAmount;
private double depositAmount;
private double closingBalance;
#ManyToOne
#JoinColumn(name="userDetailsId", referencedColumnName="user_id")
private UserDetails userDetails;
#ManyToOne
#JoinColumn(name="expenseCategoriesId", referencedColumnName="category_id")
private ExpensesCategories expenseCategories;
public TransactionHistory(int userId, Date dateOfTransaction, String transactionType, String refNo, Date valueDate,
double withdrawalAmount, double depositAmount, double closingBalance) {
this.dateOfTransaction = dateOfTransaction;
this.transactionType = transactionType;
this.refNo = refNo;
this.valueDate = valueDate;
this.withdrawalAmount = withdrawalAmount;
this.depositAmount = depositAmount;
this.closingBalance = closingBalance;
}
public TransactionHistory() {
}
public Date getDateOfTransaction() {
return dateOfTransaction;
}
public void setDateOfTransaction(Date date) {
this.dateOfTransaction = date;
}
public String getTransactionType() {
return transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public String getRefNo() {
return refNo;
}
public void setRefNo(String refNo) {
this.refNo = refNo;
}
public Date getValueDate() {
return valueDate;
}
public void setValueDate(Date valueDate) {
this.valueDate = valueDate;
}
public double getWithdrawalAmount() {
return withdrawalAmount;
}
public void setWithdrawalAmount(double withdrawalAmount) {
this.withdrawalAmount = withdrawalAmount;
}
public double getDepositAmount() {
return depositAmount;
}
public void setDepositAmount(double depositAmount) {
this.depositAmount = depositAmount;
}
public double getClosingBalance() {
return closingBalance;
}
public void setClosingBalance(double closingBalance) {
this.closingBalance = closingBalance;
}
public UserDetails getUserDetails() {
return userDetails;
}
public void setUserDetails(UserDetails userDetails) {
this.userDetails = userDetails;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public ExpensesCategories getExpenseCategories() {
return expenseCategories;
}
public void setExpenseCategories(ExpensesCategories expenseCategories) {
this.expenseCategories = expenseCategories;
}
}
Table: User Details
#Entity
#Table(name = "Employee")
public class UserDetails {
#Id
#Column(name = "user_id", unique = true)
private int id;
#NotNull
private String firstname;
#NotNull
private String lastname;
#Column(unique = true)
#NotNull
private String emailaddress;
#NotNull
private String role;
public UserDetails(String firstname, String lastname, String emailaddress, String role) {
this.firstname = firstname;
this.lastname = lastname;
this.emailaddress = emailaddress;
this.role = role;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public UserDetails() {
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmailaddress() {
return emailaddress;
}
public void setEmailaddress(String emailaddress) {
this.emailaddress = emailaddress;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#Override
public String toString() {
return "Employee [id=" + id + ", firstname=" + firstname + ", lastname=" + lastname + ", emailaddress="
+ emailaddress + ", role=" + role + "]";
}
I have written query like this in transaction entity.
#Query( nativeQuery=true, value="SELECT a.expense_categories_id, a.Total_withdrawal_Amount, b.category_code_in_bank_stats, b.category_name FROM (SELECT expense_categories_id , SUM(withdrawal_amount) AS Total_withdrawal_Amount FROM transaction_history GROUP BY expense_categories_id) a join expenses_categories b on a.expense_categories_id = b.category_id
")
List<Object[]> getCategorizedExpenses();
My Json Response is like:
[
[
1,
21,
"UPI",
"UPI Payments"
],
[
2,
3733.59,
"POS",
"Shopping"
]
]
But i want json response with column names as well:
[
[
expense_categories_id: 1,
Total_withdrawal_Amount: 21,
category_code_in_bank_stats: "UPI",
category_name: "UPI Payments"
],
[
expense_categories_id: 2,
Total_withdrawal_Amount: 3733.59,
category_code_in_bank_stats: "POS",
category_name: "Shopping"
]
]
Please help me out..
You would need to map the results directly to a POJO class and ad some json config:
1) Define the pojo
public ResultClass implements Serializable{
#JsonProperty("expense_categories_id")
private Integer expenseCategoriesId;
...
public ResultClass(Integer expenseCategoriesId ... // rest params){
this.expenseCategoriesId = expenseCategoriesId;
...
}
}
2) Define the mapping:
#SqlResultSetMapping(
name="myMapping",
classes={
#ConstructorResult(
targetClass=ResultClass.class,
columns={
#ColumnResult(name="expenseCategoriesId"),
#ColumnResult(name="totalWithdrawalAmount")
// further mappings ...
}
)
}
)
3) Define a native query
#NamedNativeQuery(name="TransactionHistory.myQuery"
, query="SELECT new mypackage.ResultClass(a.expense_categories_id as expeneCategoriesId ... ) from ...")
4) Define this method in the CrudRepository without the #Query annotation:
public List<ResultClass> myQuery();
Teh #SqlResultSetMapping and #NamedNativeQuery would need to be defined on one of your mapped entities.
Your native query will give you an object[][] as an result. So, it actually a mxn rows.
So,
I think you should create a class names Response
public class Response{
private Long expense_categories_id;
private Double Total_withdrawal_Amount;
private String category_code_in_bank_stats;
private String category_name;
//getters and setters for all attributes
}
List<Response> fillCategorizedExpenses(){
List<Response> response_List = new ArrayList<>();
Response response = null;
Object[][] // fill each object with by accessing their index from
//this array.
for() //iterate the object array. {
response = new Response();
response.setExpense_categories_id(value); // set all attributes.
....
....
....
response_List.add(response);
}
return response_List; //this will print as you need in your project.
}
Thank You :) Hope this might help you out.
I am trying to save an object into DynamoDB. I know that the easiest way to do this is to annotate the object with #DynamoDBDocument.
However, in my case, the objects I want to save belong to a package that I can't modify.
I am using the java sdk.
import not.my.package.Outsider;
#DynamoDBTable(tableName = "DynamoTable")
public class DynamoTable {
private Outsider outsider;
//getters...
//setters...
}
Any ideas on how I can save these objects? I do not want to save them as a string as we are using a Dynamo to SQL plugin for our business purposes.
Thanks.
Firstly, the OP doesn't have any information about partition key and sort key. The below code auto generates the partition key using annotation #DynamoDBAutoGeneratedKey. You can change it based on your use case.
Order class - Similar to DynamoTable
#DynamoDBTable(tableName = "Order")
public class Order implements Serializable {
private static final long serialVersionUID = -3534650012619938612L;
private String orderId;
private String productName;
private Integer createDate;
private Outsider outsider;
#DynamoDBHashKey(attributeName = "orderId")
#DynamoDBAutoGeneratedKey
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
#DynamoDBAttribute(attributeName = "productName")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
#DynamoDBAttribute(attributeName = "createDate")
public Integer getCreateDate() {
return createDate;
}
public void setCreateDate(Integer createDate) {
this.createDate = createDate;
}
#DynamoDBAttribute(attributeName = "outsider")
public Outsider getOutsider() {
return outsider;
}
public void setOutsider(Outsider outsider) {
this.outsider = outsider;
}
}
Outsider class:-
The attributes in outsider class will be saved as Map attribute in DynamoDB table.
#DynamoDBDocument
public class Outsider implements Serializable{
private static final long serialVersionUID = 4449726365885112352L;
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Code to save data:-
This code should work as long as you have dynamoDBClient object. I have used Spring to inject the object to my service class. There are multiple ways.
public Boolean createOrderWithOutsider(String productName, Outsider outsider) {
DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient);
Order order = new Order();
order.setProductName(productName);
order.setOutsider(outsider);
dynamoDBMapper.save(order);
System.out.println("Order id : " + order.getOrderId());
return true;
}
Test code:-
#Test
public void createOrderWithOutsider() {
Outsider outsider = new Outsider();
outsider.setFirstName("John");
outsider.setLastName("Micheal");
Assert.isTrue(tableOperations.createOrderWithOutsider("Pepsi", outsider));
}
Connection sample:-
<bean id="amazonDynamoDB" class="com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient">
<constructor-arg ref="amazonAWSCredentials" />
<property name="endpoint" value="${amazon.dynamodb.endpoint}" />
</bean>
Autowired in service class:-
#Autowired
private AmazonDynamoDBClient dynamoDBClient;
Sample data saved in table:-
I'm new to Java and even more newer to Spring (Boot and JPA) but I was curious, I'm trying to debug an issue that says, "No identifier specified for entity".
For illustartion purposes, I've created the following tables from this diagram:
Originally, there was a M:N relationship between the user and vehicle table, so I created an associative entity (UserVehicleAsso) to split the two up. I was following this guide on M:N mapping in Java, http://viralpatel.net/blogs/hibernate-many-to-many-annotation-mapping-tutorial/
For the most part, it was pretty straight forward but my question is, within the associative entity (UserVehicleAsso), do I have to use the #Id annotation for each of the foreign keys? I assume that I didn't need to because those were automatically generated from each of the respective tables.
Let me know your thoughts or comments, thanks.
Also, below is the code that I used to generate these models:
For the User table/class:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
private String fName;
private String lName;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="userVehicleAsso",
joinColumns={#JoinColumn(name="userID")},
inverseJoinColumns={#JoinColumn(name="vehicleID")})
private Set<Vehicle> vehicles = new HashSet<Vehicle>();
//constructor
protected User() {}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getFName() {
return fName;
}
public void setFName(String fName) {
this.fName = fName;
}
public String getLName() {
return lName;
}
public void setLName(String lName) {
this.lName = lName;
}
public Set<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(Set<Vehicle> vehicles) {
this.vehicles = vehicles;
}
#Override
public String toString() {
return getFName() + "," + getLName();
}}
For the Vehicle table/class:
#Entity
public class Vehicle {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int vehicleId;
private String brand;
private String model;
//foreign key mappings
//mapping with associative
#ManyToMany(mappedBy="vehicles")
private Set<User> users = new HashSet<User>();
//constructors
protected Vehicle() {}
public Vehicle(int id) {
this.vehicleId = id;
}
public Vehicle (String brand, String model) {
this.brand = brand;
this.model = model;
}
/* public Vehicle() {
}*/
public int getVehicleId() {
return vehicleId;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
#Override
public String toString() {
// + setBodyType() + "," +
return getBrand() + "," + getModel();
}
}
And then finally, my associtive table/class:
#Entity
public class UserVehicleAsso{
private int userID;
private int vehicleID;
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public int getVehicleID() {
return vehicleID;
}
public void setVehicleID(int vehicleID) {
this.vehicleID = vehicleID;
}
}
In my opinion, it's not necessary to have an Entity class for the middle table in your case. The table will be generated automatically if configured correctly. In this table, there would not be column ID, only two columns with userID and vehicleID data.
Now, if your middle table has more than what are needed to establish the M:N relationship, then your middle Entity class is needed, and the ID of it, too. For example, if this class is intended to store the time stamp every time a relationship is established, you have to:
Create this Entity class,
Give it an ID field with proper generation strategy,
Map the time stamp with a field with adequate type, annotation/XML mapping and so on.
This part of JPA/Hibernate have confused me a lot and I used to get into them. If my memory serves me well this is the proper/perfect way how things should work.
You can specify a composite primary key class that is mapped to multiple fields or properties of the entity.
Here are sample codes:
public class ActivityRegPK implements Serializable {
private int activityId;
private int memberId;
public int getActivityId() {
return activityId;
}
public void setActivityId(int activityId) {
this.activityId = activityId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
}
associtive table/class:
#IdClass(ActivityRegPK.class)
#Entity
#Table(name="activity_reg")
#NamedQuery(name="ActivityReg.findAll", query="SELECT a FROM ActivityReg a")
public class ActivityReg implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="activity_id")
private int activityId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="ins_date")
private Date insDate;
#Id
#Column(name="member_id")
private int memberId;
}
Activity.class
#Entity
#NamedQuery(name="Activity.findAll", query="SELECT a FROM Activity a")
public class Activity implements Serializable {
// some attributes
}