Well just like the title says, I have a many to many relationship in my project, when customer can have many coupons and the other way. To make that work I made another table in MySQL which include coupon id and customer id(each row)but somehow every time I add a coupon to a customer It double its rows in coupon_customer table.
for example:
coupon-> id 1
customer->id 4
first add
now I add another coupon(id 2) to the same customer and that's the result:
second add
my code:
Customer:
#Entity
#Table(name = "customer")
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "name")
private String name;
#Column(name = "password")
private String password;
#ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH,
CascadeType.REFRESH })
#JoinTable(name = "coupon_customer", joinColumns = #JoinColumn(name = "customer_id"), inverseJoinColumns = #JoinColumn(name = "coupon_id"))
private List<Coupon> coupons;
public Customer() {
}
public Customer(String name, String password) {
this.name = name;
this.password = password;
this.coupons = new ArrayList<Coupon>();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#JsonIgnore
public List<Coupon> getCoupons() {
return coupons;
}
public void setCoupons(ArrayList<Coupon> coupons) {
this.coupons = coupons;
}
#Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", password=" + password + "]";
}
}
Coupon:
#Entity
#Table(name = "coupon")
public class Coupon {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "title")
private String title;
#Column(name = "start_date")
private Date startDate;
#Column(name = "end_date")
private Date endDate;
#Column(name = "amount")
private int amount;
#Enumerated(EnumType.STRING)
#Column(name = "type")
private CouponType type;
#Column(name = "message")
private String message;
#Column(name = "price")
private double price;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "company_id")
private Company company;
#ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH,
CascadeType.REFRESH })
#JoinTable(name = "coupon_customer", joinColumns = #JoinColumn(name = "coupon_id"), inverseJoinColumns = #JoinColumn(name = "customer_id"))
private List<Customer> customers;
public Coupon() {
}
public Coupon(String title, Date startDate, Date endDate, int amount, CouponType type, String message,
double price) {
this.title = title;
this.startDate = startDate;
this.endDate = endDate;
this.amount = amount;
this.type = type;
this.message = message;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public CouponType getType() {
return type;
}
public void setType(CouponType type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
#JsonIgnore
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
#JsonIgnore
public List<Customer> getCustomers() {
return customers;
}
public void setCustomers(List<Customer> customers) {
this.customers = customers;
}
#Override
public String toString() {
return "Coupon [id=" + id + ", title=" + title + ", startDate=" + startDate + ", endDate=" + endDate
+ ", amount=" + amount + ", type=" + type + ", message=" + message + ", price=" + price + "]";
}
CustomerController:
#RequestMapping(value = "/purchaseCoupon")
public ResponseEntity<CouponSystemResponse> purchaseCoupon(#RequestParam(value = "id") int id) {
try {
Coupon coupon = couponService.getCoupon(id);
getEntity().getCoupons().add(coupon); --> getEntity() gets the customer
coupon.setAmount(coupon.getAmount() - 1);
customerService.updateCustomer(getEntity()); --> updates customer after purchase coupon
couponService.updateCoupon(coupon); --> update coupon after been purchased(amount -1)
.....
and if that helps MySQL script:
DROP SCHEMA IF EXISTS `couponsystem`;
CREATE SCHEMA `couponsystem`;
use `couponsystem`;
DROP TABLE IF EXISTS `company`;
CREATE TABLE `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL UNIQUE,
`password` varchar(20) NOT NULL,
`email` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
);
DROP TABLE IF EXISTS `coupon`;
CREATE TABLE `coupon` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(20) NOT NULL UNIQUE,
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
`amount` int DEFAULT NULL,
`type` varchar(15) DEFAULT NULL,
`message` varchar(50) DEFAULT NULL,
`price` float DEFAULT NULL,
`company_id` int(11),
PRIMARY KEY (`id`),
KEY `FK_company_id` (`company_id`),
CONSTRAINT `FK_company_id` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);
DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL UNIQUE,
`password` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `coupon_customer`(
`coupon_id` int(11) NOT NULL,
`customer_id` int(11) NOT NULL,
/*
PRIMARY KEY (`coupon_id`,`customer_id`), --> that's in comment only cause I got exception every time row doubles itself and tried looking for solutions
*/
CONSTRAINT `FK_coupon_id` FOREIGN KEY (`coupon_id`) REFERENCES `coupon` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);
CustomerService:
#Service
public class CustomerService {
#Autowired
CustomerRepository customerRepo;
.....
public void updateCustomer(Customer customer) {
customerRepo.save(customer);
}
.....
CouponService:
#Service
public class CouponService {
#Autowired
CouponRepository couponRepo;
......
public void updateCoupon(Coupon coupon) {
couponRepo.save(coupon);
}
......
Weird stuff.Like it takes all the last rows add them and then add another rows. I thought i something with cascade but couldn't make that work.... appreciate any help.
1st of all I would add another constraint to the coupon_customer table, a unique combination, provided with an INSERT IGNORE conmand, that will skip insert errors, it will provide basic db protection of such errors
ALTER TABLE coupon_customer ADD UNIQUE KEY coupon_customer (coupon_id, customer_id);
and the INSERT should be:
INSERT IGNORE INTO...
Beyond that, the function generating the query should receive exactly one parameter for each key and generate the simplest query. If the insert js built with select or the function works on the function with arrays, then these can generate errors as you described
public function add coupon($customer_id, $coupon_id) {
...
$sql = "INSERT IGNORE INTO coupon_customer VALUES (". $customer_id . ",". $coupon_id . ");" ;
...
}
Your Coupon_Customer primary key should be composed by two fields (customer_id and coupon_id).
Looking at your code, you don't have any primary key at this table. That's the main problem.
In order to create a composed primary key in Spring Data JPA, you do need a #Embeddable annotated class, which will represent your coupon_customer_id.
Something like the following:
CouponCustomerId.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class CouponCustomerId implements Serializable {
#Column(name = "coupon_id")
private Long couponId;
#Column(name = "customer_id")
private Long customerId;
public CouponCustomerId(Long couponId, Long customerId) {
this.couponId = couponId;
this.customerId = customerId;
}
// getters and setters..
}
Now, you'll need to create a CouponCustomer entity with an #EmbeddedId, which will represent your composed primary key.
CouponCustomer.java
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.OneToMany;
#Entity
public class CouponCustomer {
#EmbeddedId
private CouponCustomerId id;
#ManyToOne(fetch = FetchType.LAZY) // add your own ManyToOne configurations
#MapsId("couponId")
private Coupon coupon;
#ManyToOne(fetch = FetchType.LAZY) // add your own ManyToOne configurations
#MapsId("customerId")
private Customer customer;
// getters and setters..
}
Now, at your Customer entity, you'll have to change your List<Coupon> to List<CouponCustomer> and change the relationship to #OneToMany.
Customer.java
....
#OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH
})
private List<CouponCustomer> coupons;
....
Same thing for the Coupon entity.
Coupon.java
....
#OneToMany(mappedBy = "coupon" fetch = FetchType.LAZY, cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH
})
private List<CouponCustomer> customers;
....
Now, each time you add a coupon to a customer, you just need to relate it's ids.
Something like the following:
#RequestMapping(value = "/purchaseCoupon")
public ResponseEntity < CouponSystemResponse > purchaseCoupon(#RequestParam(value = "id") int id) {
try {
Coupon coupon = couponService.getCoupon(id);
coupon.setAmount(coupon.getAmount() - 1);
couponService.updateCoupon(coupon); -->update coupon after been purchased(amount - 1)
CouponCustomer cc = new CouponCustomer();
// assuming that getEntity() gets your Customer
cc.setCoupon(coupon);
cc.setCustomer(getEntity();
cc.setId(new CouponCustomerId(coupon.getId(), getEntity().getId()));
couponCustomerService.save(cc);
.....
Keep in mind that, in order to update the Coupon and creating a record in Coupon_customer, you don't need to call customerService.updateCustomer.
At
cc.setId(new CouponCustomerId(coupon.getId(), getEntity().getId()));
couponCustomerService.save(cc);
You're creating a record to the coupon_customer table, with the composed primary key (coupon_id, customer_id).
Hope this helps.
Related
I have two models and when i try to add a new file the file_id is null.No error message it works fine except that null. How can I fix that?
Customer :
#NoArgsConstructor
#AllArgsConstructor
#Data
#Builder
#Entity
#Table(name = "customer")
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String CustomerName;
private String email;
#OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true)
private List<File> File = new ArrayList<>();
}
File :
#NoArgsConstructor
#AllArgsConstructor
#Data
#Builder
#Entity
#Table(name = "file")
public class File implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String file_name;
#ManyToOne
#JoinColumn(name="customer_id")
private Customer Customer;
}
Repository :
#Repository
public interface FileRepository extends JpaRepository <File,Integer> {
}
FileDTO :
#Data
public class FileDTO {
private String file_name;
private Customer customer;
CustomerDTO:
#Data
public class CustomerDTO {
private String customernamesurname;
private String email;
private Customer customer;
}
I think problem is in mapper class. I want to add integer.
FileMapper :
public class FileMapper {
public static FileDTO toDto(File file){
File DTO fileDTO = new FileDTO();
fileDTO.setFile_name(file.getFile_name());
fileDTO.setCustomer(file.getCustomer());
return fileDTO;
}
public static File toEntity(FileDTO fileDTO){
File file = new File();
file.setFile_name(fileDTO.getFile_name());
file.setCustomer(fileDTO.getCustomer());
return file;
}
CustomerMapper:
public class CustomerMapper {
public static CustomerDTO toDto(Customer customer){
CustomerDTO customerDTO = new CustomerDTO();
customerDTO.setCustomernamesurname(customer.getCustomernamesurname());
customerDTO.setEmailcustomer.getEmail());
return customerDTO;
}
public static Customer toEntity(CustomerDTO customerDTO){
Customer customer = new Customer();
customer.setCustomernamesurname(customerDTO.getCustomernamesurname());
customer.setEmail(customerDTO.getEmail());
return customer;
}
}
Controller :
#PostMapping(path = "/addFile")
public boolean addFile(#RequestBody FileDTO File) {
return FileService.addFile(FileMapper.toEntity(file));
}
FileImplemantion :
#Override
public boolean addFile(File file) {
File save = fileRepository.save(file);
if (save == null)
return false;
return true;
}
PostgreSql :
DROP TABLE IF EXISTS customer CASCADE;
DROP TABLE IF EXISTS user CASCADE;
DROP TABLE IF EXISTS file CASCADE;
CREATE TABLE customer(
id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
customernamesurname VARCHAR(100) NOT NULL,
email VARCHAR(50) NOT NULL
);
CREATE TABLE user(
id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
user_name VARCHAR(100) NOT NULL,
user_password VARCHAR(50) NOT NULL
);
CREATE TABLE file(
id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
file_name VARCHAR(100) NOT NULL,
customer_id INT,
FOREIGN KEY (customer_id) REFERENCES customer (id)
);
I want to add File with JSON Content and use customer_id as foreign key. But customer_id returns null when I add file.
It works fine with customer. But I want only add file like these :
{
"file_name": "Test",
"customer_id": 2
}
It adds name but customer_id is null with that concept
You need change FileDTO:
#Data
public class FileDTO {
#JsonProperty("file_name")
private String fileName;
#JsonProperty("customer_id")
private int customerId;
}
Get customer by Id and set for File Enity
#PostMapping(path = "/addFile")
public boolean addFile(#RequestBody FileDTO file) {
Customer customer = customerRepository.findById(file.getCustomerId())
.orElseThrow(EntityNotFoundException::new);
return fileService.addFile(FileMapper.toEntity(file, customer));
}
public class FileMapper {
public static File toEntity(FileDTO fileDTO, Customer customer) {
File file = new File();
file.setFile_name(fileDTO.getFileName());
file.setCustomer(customer);
return file;
}
}
I have Entities (Student,StudentSkills, StudentEmpSkills)
Student.java
#Entity
#Table(name = "Student", catalog = "dbs")
public class Student implements java.io.Serializable {
private int id;
...
...
private Set<StudentSkills> studentSkills= new HashSet<StudentSkills>(0);
private Set<StudentEmpSkills> studentEmpSkills= new HashSet<StudentEmpSkills>(0);
#OneToMany(fetch = FetchType.EAGER, mappedBy = "Student")
public Set<StudentSkills> getStudentSkills() {
return this.studentEmpSkills;
}
public void setStudentSkills(
Set<StudentSkills> studentSkills) {
this.studentSkills = studentSkills;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "Student")
public Set<StudentEmpSkills> getStudentEmpSkills() {
return this.StudentEmpSkills;
}
public void setStudentEmpSkills(
Set<StudentEmpSkills> studentEmpSkills) {
this.studentEmpSkills= studentEmpSkills;
}
}
in StudentEmpSkills.java
#Entity
#Table(name = "studentEmpSkills", catalog = "npdbs")
public class StudentEmpSkills implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private StudentEmpSkillsId id;
private Student Student ;
......
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "studentID", nullable = false, insertable = false, updatable = false)
public Student getStudent() {
return student;
}
In the above we are getting the Set of StudentEmpSkils from Student by one to many and many to one relation.
as we are getting Student from StudentEmpSkill
In JoinColumn we are giving studentID column to fetch the abject.
Now I want to get StudentSkill object from StudentEmpSkills.
StudentSkills - (studentID* | skillID*) | skillname
StudentEmpSkills - (studentID* | skillID* | empID*) | empName
(..) - composit primary key
So I want to fetch StudentSkills from StudentEmpSkill
What I need to write in StudentEmpSkills to fetch StudentSkill. because we have composit primary key in StudentSkill.
How to map the StudentSkill to StudentEmpSkills.
Can anyone please suggest?
My aim is to learn JavaEE and what better way to do so than to work on a project. So I set out to create a Stock Market simulation web application.
Naturally a person owns some stock identified by a company ticker (company_id) and an associated number of shares owned. So I put these in a Map.
Here are the mysql ddl statements;
For the users table
CREATE TABLE `users` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT,
`firstName` varchar(30) NOT NULL,
`lastName` varchar(30) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=latin1;
For the portfolios table,
CREATE TABLE `portfolios_tb` (
`user_id` bigint(20) NOT NULL,
`company_id` varchar(4) NOT NULL,
`shares_owned` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`user_id`,`company_id`),
KEY `company_id` (`company_id`),
CONSTRAINT `company_id` FOREIGN KEY (`company_id`) REFERENCES `stocks` (`company_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `uid` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The Stock entity
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
/**
*
*/
#Entity
#Table(name = "stocks")
public class Stock implements Serializable {
#Id
#GeneratedValue
#Column(name = "company_id")
String stockId;
#NotNull #Column(name="company_name")
String companyName;
#NotNull #Column(name="shares_listed")
BigInteger sharesListed;
#Column(name="par_value")
BigDecimal parValue;
#Column(name="current_Price")
BigDecimal currentPrice;
public Stock(){
}
public Stock(String stockId, String companyName, BigInteger sharesListed){
this.companyName = companyName;
this.stockId = stockId;
this.sharesListed = sharesListed;
this.parValue = BigDecimal.ZERO;
this.currentPrice = BigDecimal.ZERO;
}
public String getStockId() {
return stockId;
}
public void setStockId(String stockId) {
this.stockId = stockId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public BigInteger getSharesListed() {
return sharesListed;
}
public void setSharesListed(BigInteger sharesListed) {
this.sharesListed = sharesListed;
}
public BigDecimal getParValue() {
return parValue;
}
public void setParValue(BigDecimal parValue) {
this.parValue = parValue;
}
public BigDecimal getCurrentPrice() {
return currentPrice;
}
public void setCurrentPrice(BigDecimal currentPrice) {
this.currentPrice = currentPrice;
}
}
The User entity
import java.io.Serializable;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;
#Entity
#Table(name = "users")
public class User implements Serializable {
#Id
#GeneratedValue
private String user_id; //I know its not convention, was experimenting.
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#ElementCollection
#CollectionTable(name = "portfolios_tb")
#MapKeyColumn(name = "company_id")
#Column(name = "shares_owned")
Map<String, BigInteger> stocksOwned = new HashMap<>();
public User() {
}
public User(String firstName, String lastName) {
this.stocksOwned = new HashMap<>();
this.firstName = firstName;
this.lastName = lastName;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
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 Map<String, BigInteger> getStocksOwned() {
return stocksOwned;
}
public void setStocksOwned(Map<String, BigInteger> stocksOwned) {
this.stocksOwned = stocksOwned;
}
}
Here's the main class
public class Main {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hisaMarket_Version2PU");
EntityManager em = emf.createEntityManager();
public static void main(String[] args) {
Main main = new Main();
main.getUsers();
}
public void getUsers(){
EntityTransaction tx = em.getTransaction();
tx.begin();
TypedQuery<User> query = em.createQuery("SELECT u FROM User u", User.class);
List<User> users = query.getResultList();
for(User user : users){
System.out.print(user.getFirstName() + " "+ user.getLastName() +" owns ");
Map<String,BigInteger> stocks = user.getStocksOwned();
Set<String> keys = stocks.keySet();
//planning to display Map key and corresponding value
System.out.println();
}
tx.commit();
em.close();
emf.close();
}
When I run it I get this message from eclipselink
Error Code: 1054
Call: SELECT t0.shares_owned, t0.company_id FROM portfolios_tb t0 WHERE (t0.User_USER_ID = ?)
bind => [1 parameter bound]
Query: DataReadQuery(name="stocksOwned" sql="SELECT t0.shares_owned, t0.company_id FROM portfolios_tb t0 WHERE (t0.User_USER_ID = ?)")
Why is eclipselink concatenating the entityname (User) and the enitityId (user_id) to give this t0.User_USER_ID = ? instead of this "....to.user_id"
That's because you didn't specify #JoinColumn for that mapping, so JPA's default mechanism is generating the join column name like <entity_name>_<id_column_name>.
Just add #JoinColumn(name = "user_id") attribute on #CollectionTable map mapping and it should work.
#ElementCollection
#CollectionTable(name = "portfolios_tb", joinColumns = #JoinColumn(name = "user_id"))
#MapKeyColumn(name = "company_id")
#Column(name = "shares_owned")
Map<String, BigInteger> stocksOwned = new HashMap<>();
Hi my relation throws #EmbeddedId throws IdIdentifierGenerationException: null id. Any advices is welcome. Here is my Code:
TABLE ACTIVIDADES(
CODIGO CHAR(10) NOT NULL UNIQUE,
NOMBRE VARCHAR(50) UNIQUE,
PRIMARY KEY(CODIGO)
)ENGINE=INNODB;
CREATE TABLE EVENTOS_ACTIVIDADES(
ID INT AUTO_INCREMENT,
CODIGO_ACTIVIDADES CHAR(10) NOT NULL UNIQUE,
PRIMARY KEY(ID,CODIGO_ACTIVIDADES),
FOREIGN KEY(CODIGO_ACTIVIDADES) REFERENCES ACTIVIDADES(CODIGO) ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE=INNODB;
Here are my JPA Entities:
#Entity
#Table(name = "eventos_actividades", catalog = "capacitacion_csg", uniqueConstraints = #UniqueConstraint(columnNames = "CODIGO_ACTIVIDADES"))
public class EventosActividades implements java.io.Serializable {
private EventosActividadesId id;
private Actividades actividades;
public EventosActividades() {
}
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "id", column = #Column(name = "ID", nullable = false)),
#AttributeOverride(name = "codigoActividades", column = #Column(name = "CODIGO_ACTIVIDADES", unique = true, nullable = false, length = 10)) })
public EventosActividadesId getId() {
return this.id;
}
public void setId(EventosActividadesId id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "CODIGO_ACTIVIDADES", unique = true, nullable = false, insertable = false, updatable = false)
public Actividades getActividades() {
return this.actividades;
}
public void setActividades(Actividades actividades) {
this.actividades = actividades;
}
#Entity
#Table(name="ACTIVIDADES", catalog="CAPACITACION_CSG", uniqueConstraints = {#UniqueConstraint(columnNames="NOMBRE"), #UniqueConstraint(columnNames="CODIGO")})
public class Actividades {
private String codigo;
private String nombre;
private List<EventosActividades> eventosActividades;
#Column(name="NOMBRE",unique=true,nullable=false,length=50)
public String getNombre() {
return nombre;
}
#Id
#Column(name="CODIGO",unique=true,nullable=false,length=10)
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
#OneToMany(fetch= FetchType.EAGER,mappedBy="actividades",cascade=CascadeType.ALL)
public List<EventosActividades> getEventosActividades() {
return eventosActividades;
}
public void setEventosActividades(List<EventosActividades> eventosActividades) {
this.eventosActividades = eventosActividades;
}
}
#Embeddable
public class EventosActividadesId implements java.io.Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String codigoActividades;
public EventosActividadesId() {
}
public EventosActividadesId(int id, String codigoActividades) {
this.id = id;
this.codigoActividades = codigoActividades;
}
#Column(name = "ID", nullable = false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "CODIGO_ACTIVIDADES", unique = true, nullable = false, length = 10)
public String getCodigoActividades() {
return this.codigoActividades;
}
public void setCodigoActividades(String codigoActividades) {
this.codigoActividades = codigoActividades;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof EventosActividadesId))
return false;
EventosActividadesId castOther = (EventosActividadesId) other;
return (this.getId() == castOther.getId())
&& ((this.getCodigoActividades() == castOther
.getCodigoActividades()) || (this
.getCodigoActividades() != null
&& castOther.getCodigoActividades() != null && this
.getCodigoActividades().equals(
castOther.getCodigoActividades())));
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getId();
result = 37
* result
+ (getCodigoActividades() == null ? 0 : this
.getCodigoActividades().hashCode());
return result;
}
}
THANKS for everyone, I've not initialize my #Embeddable EventosActividadesId class and set in my EventosActividades Entity like this way:
EventosActividadesId id = new EventosActividadesId();
id.setCodigoActividades("ACTCBK");
eventosActividades.setId(id);
I have this example, witch it works, I just want to modify it but I can't do it.
Here is the link of the example :example link
Anyway I posting it here to:
Here is the picture of entitys :
Entity-Relation
CREATE TABLE `stock` (
`STOCK_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`STOCK_CODE` VARCHAR(10) NOT NULL,
`STOCK_NAME` VARCHAR(20) NOT NULL,
PRIMARY KEY (`STOCK_ID`) USING BTREE,
UNIQUE KEY `UNI_STOCK_NAME` (`STOCK_NAME`),
UNIQUE KEY `UNI_STOCK_ID` (`STOCK_CODE`) USING BTREE
)
CREATE TABLE `category` (
`CATEGORY_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(10) NOT NULL,
`DESC` VARCHAR(255) NOT NULL,
PRIMARY KEY (`CATEGORY_ID`) USING BTREE
)
CREATE TABLE `stock_category` (
`STOCK_ID` INT(10) UNSIGNED NOT NULL,
`CATEGORY_ID` INT(10) UNSIGNED NOT NULL,
`CREATED_DATE` DATE NOT NULL,
`CREATED_BY` VARCHAR(10) NOT NULL,
PRIMARY KEY (`STOCK_ID`,`CATEGORY_ID`),
CONSTRAINT `FK_CATEGORY_ID` FOREIGN KEY (`CATEGORY_ID`)
REFERENCES `category` (`CATEGORY_ID`),
CONSTRAINT `FK_STOCK_ID` FOREIGN KEY (`STOCK_ID`)
REFERENCES `stock` (`STOCK_ID`)
)
And here are the java classes:
Stock.java
package com.mkyong.stock;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name = "stock", catalog = "mkyongdb", uniqueConstraints = {
#UniqueConstraint(columnNames = "STOCK_NAME"),
#UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
private Integer stockId;
private String stockCode;
private String stockName;
private Set<StockCategory> stockCategories = new HashSet<StockCategory>(0);
public Stock() {
}
public Stock(String stockCode, String stockName) {
this.stockCode = stockCode;
this.stockName = stockName;
}
public Stock(String stockCode, String stockName,
Set<StockCategory> stockCategories) {
this.stockCode = stockCode;
this.stockName = stockName;
this.stockCategories = stockCategories;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
return this.stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
#Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
public String getStockCode() {
return this.stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
#Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
public String getStockName() {
return this.stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.stock", cascade=CascadeType.ALL)
public Set<StockCategory> getStockCategories() {
return this.stockCategories;
}
public void setStockCategories(Set<StockCategory> stockCategories) {
this.stockCategories = stockCategories;
}
}
StockCategory.java
package com.mkyong.stock;
import java.util.Date;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
#Entity
#Table(name = "stock_category", catalog = "mkyongdb")
#AssociationOverrides({
#AssociationOverride(name = "pk.stock",
joinColumns = #JoinColumn(name = "STOCK_ID")),
#AssociationOverride(name = "pk.category",
joinColumns = #JoinColumn(name = "CATEGORY_ID")) })
public class StockCategory implements java.io.Serializable {
private StockCategoryId pk = new StockCategoryId();
private Date createdDate;
private String createdBy;
public StockCategory() {
}
#EmbeddedId
public StockCategoryId getPk() {
return pk;
}
public void setPk(StockCategoryId pk) {
this.pk = pk;
}
#Transient
public Stock getStock() {
return getPk().getStock();
}
public void setStock(Stock stock) {
getPk().setStock(stock);
}
#Transient
public Category getCategory() {
return getPk().getCategory();
}
public void setCategory(Category category) {
getPk().setCategory(category);
}
#Temporal(TemporalType.DATE)
#Column(name = "CREATED_DATE", nullable = false, length = 10)
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
#Column(name = "CREATED_BY", nullable = false, length = 10)
public String getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
StockCategory that = (StockCategory) o;
if (getPk() != null ? !getPk().equals(that.getPk())
: that.getPk() != null)
return false;
return true;
}
public int hashCode() {
return (getPk() != null ? getPk().hashCode() : 0);
}
}
Stockcategoryid.java
package com.mkyong.stock;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
#Embeddable
public class StockCategoryId implements java.io.Serializable {
private Stock stock;
private Category category;
#ManyToOne
public Stock getStock() {
return stock;
}
public void setStock(Stock stock) {
this.stock = stock;
}
#ManyToOne
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StockCategoryId that = (StockCategoryId) o;
if (stock != null ? !stock.equals(that.stock) : that.stock != null) return false;
if (category != null ? !category.equals(that.category) : that.category != null)
return false;
return true;
}
public int hashCode() {
int result;
result = (stock != null ? stock.hashCode() : 0);
result = 31 * result + (category != null ? category.hashCode() : 0);
return result;
}
}
Category.java
package com.mkyong.stock;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "category", catalog = "mkyongdb")
public class Category implements java.io.Serializable {
private Integer categoryId;
private String name;
private String desc;
private Set<StockCategory> stockCategories = new HashSet<StockCategory>(0);
public Category() {
}
public Category(String name, String desc) {
this.name = name;
this.desc = desc;
}
public Category(String name, String desc, Set<StockCategory> stockCategories) {
this.name = name;
this.desc = desc;
this.stockCategories = stockCategories;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "CATEGORY_ID", unique = true, nullable = false)
public Integer getCategoryId() {
return this.categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
#Column(name = "NAME", nullable = false, length = 10)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "[DESC]", nullable = false)
public String getDesc() {
return this.desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.category")
public Set<StockCategory> getStockCategories() {
return this.stockCategories;
}
public void setStockCategories(Set<StockCategory> stockCategories) {
this.stockCategories = stockCategories;
}
}
Now I want for a stock to have only one Category, so basicaly I have to change from #OneToMany In Stock.java to ManyToOne but if I only changed to that it gives me error.
Can someone help me, please .
It should be something like :
#ManyToOne(fetch = FetchType.LAZY, mappedBy = "pk.stock", cascade=CascadeType.ALL)
private StockCategory stockgatery;
//setter and getter methods
//or something like
#ManyToOne
#JoinColumn(name="pk.stock"
But I can't figure it out.
Try something like this below ...
#ManyToOne #JoinColumns({ #JoinColumn(name = "STOCK_ID", referencedColumnName = "STOCK_ID"),
#JoinColumn(name = "CATEGORY_ID", referencedColumnName = "CATEGORY_ID") })
private StockCategory stockCategory;