I want to add a new Ticket to my SQL Database.
Ticket has 2 PK: event and code;
I created Entitys with Composite Keys and want to execute POST requests. I always get "Column 'seller' cannot be null". Anyone here knows how to work with Java Persistence and so on?
I tried it with IdClass and Embeddable but I get errors for both. It's just the inserting of a new Object in the Database. GET Requests work fine...
I tried different annotations but for now nothing worked. I probably don't really understand the concept of Java Persistence, but I also dont have to time to go trough it the whole way. So of it's obvious, please explain a little what it does... Thanks in advance!
My Entities:
Event.java
#Entity
#Table(name="events")
#NamedQuery(name="Event.findAll", query="SELECT e FROM Event e")
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String category;
private String city;
#Temporal(TemporalType.DATE)
private Date date;
#Column(name="image_path")
private String imagePath;
private String name;
private String venue;
//bi-directional one-to-many association to Ticket
#OneToMany(mappedBy="eventBean")
#JsonManagedReference(value="eventBean")
private List<Ticket> tickets;
public Event() {
}
Ticket.java
#Entity
#Table(name="tickets")
#IdClass(TicketPK.class)
//#NamedQuery(name="Ticket.findAll", query="SELECT t FROM Ticket t")
public class Ticket implements Serializable{
private static final long serialVersionUID = 1L;
#Id
private long code;
#Id
private long event;
private float price;
private String type;
//#Column(insertable=false, updatable=false)
//private long event;
//bi-directional many-to-one association to Event
//One Event can have many tickets
#ManyToOne(fetch = FetchType.EAGER)
#JsonBackReference(value="eventBean")
#JoinColumn(name="event",nullable = false,insertable=false,updatable=false)
private Event eventBean;
//bi-directional many-to-one association to User
//One User can have many tickets
#ManyToOne(fetch = FetchType.LAZY)
#JsonBackReference(value="seller")
#JoinColumn(name="seller", referencedColumnName = "alias")
private User user;
public Ticket() {
}
public Ticket(long event, float price, Event eventBean, User user) {
this.event = event;
this.price = price;
this.eventBean = eventBean;
this.user = user;
}
//getters and setters
public class TicketPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
//#Basic
//#GeneratedValue(strategy = GenerationType.AUTO)
//#Column(name="code", nullable=false)
private long code;
//#Basic
//#Column(name="event",insertable=false)
private long event;
public TicketPK() {
}
public TicketPK(long code, long event) {
this.code = code;
this.event = event;
}
//getters and setters
public boolean equals(Object other) {
if (this.equals(other)) {
return true;
}
if (!(other instanceof TicketPK)) {
return false;
}
TicketPK castOther = (TicketPK)other;
return
(this.code == castOther.code)
&& (this.event == castOther.event);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + ((int) (this.code ^ (this.code >>> 32)));
hash = hash * prime + ((int) (this.event ^ (this.event >>> 32)));
return hash;
}
}
User.java
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private String alias;
private String address;
#Column(name="admin_status")
private byte adminStatus;
private String name;
private String password;
#Column(name="phone_number")
private int phoneNumber;
//bi-directional one-to-many association to Ticket
//One User can have many Tickets
#OneToMany(mappedBy="user")
#JsonManagedReference(value="seller")
private List<Ticket> tickets;
public User() {
}
DAO
TicketDAO
public interface TicketDAO extends CrudRepository<Ticket, TicketPK>{
public List<Ticket> findAll();
}
Controller
#Controller
#CrossOrigin
public class MyController {
#Autowired
TicketDAO daoticket;
/****************** OPERATIONS ON Tickets ************************************/
#RequestMapping(value="/tickets", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Ticket> createTicket(#RequestBody Ticket ticket) {
ResponseEntity<Ticket> response;
Ticket newTicket = daoticket.save(ticket);
if (newTicket == null) {
response = new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
} else {
response = new ResponseEntity<>(newTicket, HttpStatus.CREATED);
}
return response;
}
}
SQL Database
CREATE DATABASE IF NOT EXISTS `BD89_03_ticketsell`;
USE `BD89_03_ticketsell`;
DROP TABLE IF EXISTS `TICKETS`;
DROP TABLE IF EXISTS `EVENTS`;
DROP TABLE IF EXISTS `USERS`;
CREATE TABLE `users` (
`name` varchar(100),
`alias` varchar(100) NOT NULL UNIQUE,
`password` varchar(100) NOT NULL,
`address` varchar(100),
`phone_number` int(10),
`admin_status` boolean NOT NULL,
PRIMARY KEY(`alias`)
);
CREATE TABLE `events`(
`id` bigint NOT NULL UNIQUE AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`category` varchar(100) NOT NULL,
`date` date NOT NULL,
`city`varchar(100) NOT NULL,
`venue` varchar(100) NOT NULL,
`image_path` varchar(300) NOT NULL,
PRIMARY KEY(`id`)
);
CREATE TABLE `tickets`(
`code` bigint NOT NULL,
`event` bigint NOT NULL,
`type` varchar(100),
`price` FLOAT(10,2) NOT NULL,
`seller` varchar(100) NOT NULL,
PRIMARY KEY(`code`, `event`),
FOREIGN KEY(`seller`) REFERENCES `users`(`alias`),
FOREIGN KEY(`event`) REFERENCES `events`(`id`)
);
INSERT INTO events (`name`, `category`, `date`, `city`, `venue`, `image_path`)
VALUES ('Cut Cupy', 'indie dance', '2024-01-22', 'Madrid', 'La Riviera', 'images/CUT-COPY2.png'),
('Dub Inc Tour 2022', 'reggae', '2021-05-03', 'Madrid', 'Sala Sol', 'images/DUB-INC-TOUR.jpg'),
('Kodaline', 'folk', '2022-03-15', 'Sevilla', 'Tablao el gitanillo', 'images/Kodaline.png');
INSERT INTO users (`name`,`alias`,`password`,`address`,`phone_number`, `admin_status`)
VALUES ('pepe', 'pepe', 'password', '17 Calle', '628791051', TRUE),
('pepe2', 'pepe2', 'password', '0 Calle', '628791052', FALSE),
('elisa', 'elisacool', 'contraseña', '3 Calle', '628791053', FALSE);
INSERT INTO tickets (`code`,`event`,`type`,`price`,`seller`)
VALUES ('1234', '1', 'palco', '17.5', 'pepe'),
('666666', '3', 'silla', '20', 'elisacool'),
('666666', '1', 'anfiteatro', '12', 'pepe2'),
('222222', '2', 'palco 3', '21.47', 'elisacool'),
('444666', '3', 'plató', '5', 'pepe'),
('111111', '2', 'palco 2', '40.99', 'elisacool');
Console Error
2022-12-06 15:52:46.186 WARN 9656 --- [io-10303-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1048, SQLState: 23000
2022-12-06 15:52:46.186 ERROR 9656 --- [io-10303-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'seller' cannot be null
2022-12-06 15:52:46.186 INFO 9656 --- [io-10303-exec-2] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2022-12-06 15:52:46.199 ERROR 9656 --- [io-10303-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Column 'seller' cannot be null
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-j-8.0.31.jar:8.0.31]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.31.jar:8.0.31]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.0.31.jar:8.0.31]
.
.
.
Related
Im trying to find one object from my DB table Real_States which goes like this:
CREATE TABLE REAL_STATES (
address VARCHAR(30) NOT NULL,
admin_id VARCHAR(15) NOT NULL,
resident_id VARCHAR(15),
real_state_type_id INT(6) NOT NULL,
block VARCHAR(3) NOT NULL,
internal_id INT(5) NOT NULL,
PRIMARY KEY (address, block, internal_id),
FOREIGN KEY (real_state_type_id) REFERENCES REAL_STATE_TYPES (real_state_type_id),
FOREIGN KEY (admin_id) REFERENCES ADMINS (admin_id),
FOREIGN KEY (resident_id) REFERENCES RESIDENTS (resident_id)
);
And I want to get a row of this table by its composite Primary Key (address, block, internal_id), all this from my EntityManager. This goes like this:
public RealState findRealState(RealStateID realStateId) {
RealState realState = em.find(RealState.class, realStateId); // first Try, which failed
List<RealState> realStates = em.createQuery("FROM RealState rs WHERE rs.realStateID.address like :" + realStateId.getAddress()).getResultList(); // second try which failed too
for (RealState realState2 : realStates) {
System.out.println(realState2.toString());
}
if (realState == null) {
throw new EntityNotFoundException("Can't find realState for ID " + realStateId.toString());
}
return realState;
}
The RealStateID Class is declared like this:
#Embeddable
public class RealStateID implements Serializable{
private static final long serialVersionUID = 6485406412363395170L;
#Column(name = "address")
private String address;
#Column(name = "block")
private String block;
#Column(name = "internal_id")
private int internal_id;
//getters..setters..
But Im just getting error by error, IDK what I am doing wrong, and I would like to figure out it. Im not using Spring, just JPA Hibernate and Java.
As it's stated in the documentation:
The primary key class must define equals and hashCode methods, consistent with equality for the underlying database types to which the primary key is mapped.
Assuming it, the method:
RealState realState = em.find(RealState.class, new RealStateID(...));
should work as expected.
EDIT Your RealStateID should look like this:
#Embeddable
public class RealStateID implements Serializable{
private static final long serialVersionUID = 6485406412363395170L;
#Column(name = "address")
private String address;
#Column(name = "block")
private String block;
#Column(name = "internal_id")
private int internal_id;`
// getters, setters
#Override
public boolean equals(Object o) {
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
RealStateID pk = (RealStateID) o;
return Objects.equals(address, pk.address) &&
Objects.equals(block, pk.block) &&
Objects.equals(internal_id, pk.internal_id);
}
#Override
public int hashCode() {
return Objects.hash(address, block, internal_id);
}
}
I'm facing an Hibernate error which says More than one row with the given identifier was found and I'm stuck with it.
I would really appreciate any help on this.
I want to create a table as orderLine that contains product code, quantity .etc for a particular sales order.
A SalesOrder can contain many orderLines.
The composite key for the orderLine table is productCode + OrderNumber. ProductCode is the primary key of the Product table and OrderNumber is the primary key of the SalesOrder table.
In a single SalesOrder there should be only one order line for a particular product.
The composite key is getting generated correctly and I get the following sql statement logged by hibernate.
Hibernate: create table orderLine (orderNumber varchar(255) not null, productCode varchar(255) not null, status varchar(255) not null, quantity integer not null, totalPrice double precision not null, unitPrice double precision not null, primary key (orderNumber, productCode))
When the OrderLine table contains data as below, I Successfully insert a new record to OrderLine table with the OrderNumber ORD001 & ProductCode BIS1003
Immediately after when I try to fetch records from the OrderLine, I'm getting the following error.
Caused by: org.hibernate.HibernateException: More than one row with the given identifier was found: BIS1003, for class: com.salesOrder_ws.entity.OrderLine
Since there is a composite key as the primary, why is hibernate throwing an exception, when only one key of the composite key is not unique?
The Code is below.
OrderLine Entity:
#Entity
#Table(name = "orderLine")
public class OrderLine implements Serializable{
private static final long serialVersionUID = -851110991599534263L;
#AttributeOverrides(value =
{#AttributeOverride(column = #Column(name="productCode"), name = "productCode"),
#AttributeOverride(column = #Column(name="orderNumber"), name = "orderNumber")})
#EmbeddedId
private LineID pk;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "productCode", insertable = false, updatable = false)
private Product product;
private int quantity;
private double unitPrice;
private double totalPrice;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "orderNumber", nullable=false, insertable=false, updatable=false)
private SalesOrder salesOrder;
#Override
public boolean equals(Object obj) {
try {
LineID line = (LineID) obj;
return (this.getSalesOrder().getOrderNumber()
.equals(line.getOrderNumber()) && this.getProduct()
.getCode().equals(line.getProductCode()));
} catch (Exception e) {
return false;
}
}
#Override
public int hashCode() {
return (this.getProduct().getCode() + "" + this.getProduct().getCode()).hashCode();
}
}
SalesOrder Entity
#Entity
#Table(name = "salesOrder")
public class SalesOrder extends BaseEntity{
#Id
private String orderNumber;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "customerCode", nullable = false)
private Customer customer;
private double totalPrice;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "salesOrder", cascade = CascadeType.ALL)
private List<OrderLine> lines;
#Override
public boolean equals(Object obj) {
try {
SalesOrder so = (SalesOrder) obj;
if (this.getOrderNumber().equals(so.getOrderNumber())) {
return true;
}
} catch (Exception e) {
return false;
}
return false;
}
#Override
public int hashCode() {
return this.getOrderNumber().hashCode();
}
}
Embeddable Class
#Embeddable
public class LineID implements Serializable{
private static final long serialVersionUID = -4478828739881744452L;
#Basic(optional = false)
private String productCode;
#Basic(optional = false)
private String orderNumber;
#Override
public boolean equals(Object obj) {
try {
LineID l = (LineID) obj;
return this.productCode.equals(l.getProductCode()) && this.orderNumber.equals(l.getOrderNumber());
} catch (Exception e) {
return false;
}
}
#Override
public int hashCode() {
return (this.getOrderNumber() + "" + this.getProductCode()).hashCode();
}
}
UPDATE
SQL generated by Hibernate :
Hibernate: create table customer (code varchar(255) not null, status varchar(255) not null, address varchar(255), creditLimit double precision not null, currentCredit double precision not null, name varchar(255), phone1 varchar(255), phone2 varchar(255), primary key (code))
Hibernate: create table orderLine (orderNumber varchar(255), productCode varchar(255), status varchar(255) not null, quantity integer not null, totalPrice double precision not null, unitPrice double precision not null, primary key (orderNumber, productCode))
Hibernate: create table product (code varchar(255) not null, status varchar(255) not null, description varchar(255), price double precision not null, quantity integer not null, primary key (code))
Hibernate: create table salesOrder (orderNumber varchar(255) not null, status varchar(255) not null, totalPrice double precision not null, customerCode varchar(255) not null, primary key (orderNumber))
Hibernate: alter table orderLine add constraint UK_9gf3j9l0n1w7d2h4sso3voc77 unique (productCode)
Hibernate: alter table orderLine add index FK_9gf3j9l0n1w7d2h4sso3voc77 (productCode), add constraint FK_9gf3j9l0n1w7d2h4sso3voc77 foreign key (productCode) references product (code)
Hibernate: alter table orderLine add index FK_ojvge4lucwf2gtihxtmnav3u2 (orderNumber), add constraint FK_ojvge4lucwf2gtihxtmnav3u2 foreign key (orderNumber) references salesOrder (orderNumber)
Hibernate: alter table salesOrder add index FK_4lq8ynumala22y9t17ceawo81 (customerCode), add constraint FK_4lq8ynumala22y9t17ceawo81 foreign key (customerCode) references customer (code)
Hibernate: alter table orderLine add constraint UK_9gf3j9l0n1w7d2h4sso3voc77 unique (productCode)
The above SQL is not intended to generate. If I could avoid this unique constraint, the problem will be solved.
Appreciate any help to resolve this issue.
I think you might be missing the #MapsId annotation:
#Entity
#Table(name = "orderLine")
public class OrderLine implements Serializable{
private static final long serialVersionUID = -851110991599534263L;
#AttributeOverrides(value =
{#AttributeOverride(column = #Column(name="productCode"), name = "productCode"),
#AttributeOverride(column = #Column(name="orderNumber"), name = "orderNumber")})
#EmbeddedId
private LineID pk;
#ManyToOne(cascade = CascadeType.ALL)
#MapsId("productCode")
private Product product;
private int quantity;
private double unitPrice;
private double totalPrice;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("orderNumber")
private SalesOrder salesOrder;
#Override
public boolean equals(Object obj) {
try {
LineID line = (LineID) obj;
return (this.getSalesOrder().getOrderNumber()
.equals(line.getOrderNumber()) && this.getProduct()
.getCode().equals(line.getProductCode()));
} catch (Exception e) {
return false;
}
}
#Override
public int hashCode() {
return (this.getProduct().getCode() + "" + this.getProduct().getCode()).hashCode();
}
}
I am getting Column not found error during, and I can't figure out what is wrong, so I ask for help.
I need to generate a list of Task that references User and Project.
I am using h2 database.
Here are the tables:
CREATE TABLE TASK.APP_USER (
id INT NOT NULL GENERATED ALWAYS AS IDENTITY,
username VARCHAR(25) NOT NULL,
firstName VARCHAR(25) NOT NULL,
lastName VARCHAR(25) NOT NULL,
password VARCHAR(32) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE TASK.PROJECT (
id INT GENERATED ALWAYS AS IDENTITY,
name VARCHAR(50) NOT NULL,
companyName VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE TASK.PROJECT_TASK (
id INT GENERATED ALWAYS AS IDENTITY,
projectId INT NOT NULL,
userId INT NOT NULL,
description VARCHAR(500) NOT NULL,
estimatedDurationHours INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (projectId) REFERENCES TASK.PROJECT(id),
FOREIGN KEY (userId) REFERENCES TASK.APP_USER(id),
);
Here is the DAO class:
#Repository
public class TaskDaoHibernate implements TaskDao {
public TaskDaoHibernate() {
}
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
#Override
public List<User> fetchAllUsers() {
return getCurrentSession().createQuery("from User").list();
}
#Override
public User fetchUserById(Integer userId) {
return (User) getCurrentSession().get(User.class, userId);
}
#SuppressWarnings("unchecked")
#Override
public List<Project> fetchAllProjects() {
return getCurrentSession().createQuery("from Project").list();
}
#Override
public Project fetchProjectById(Integer projectId) {
return (Project) getCurrentSession().get(Project.class, projectId);
}
#Override
public void saveTask(Task task) {
getCurrentSession().save(task);
}
#SuppressWarnings("unchecked")
#Override
public List<Task> fetchAllTasks() {
return getCurrentSession().createQuery("from Task").list();
}
#Override
public Task fetchTaskById(Integer taskId) {
return (Task) getCurrentSession().get(Task.class, taskId);
}
#Override
public void editTask(Task task) {
getCurrentSession().update(task);
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
Here is the User class, I've mapped Project class on same principle:
#Entity
#Table(name="TASK.PROJECT")
public class Project implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "ID")
#GeneratedValue
private Integer id;
#Column(name = "NAME")
private String nazivProjekta;
#Column(name = "COMPANYNAME")
private String nazivTvrtke;
#ManyToOne
#JoinColumn(name="PROJECTID")
private Task task;
//setters, getters and overrided equal and hashcode methods
And last class is the Task class:
#Entity
#Table(name="TASK.PROJECT_TASK")
public class Task implements Serializable {
/**
*
*/
private static final long serialVersionUID = -4633753821563474175L;
#OneToMany(mappedBy="id", fetch=FetchType.EAGER)
private List<User> user;
#OneToMany(mappedBy="id", fetch=FetchType.EAGER)
private List<Project> project;
#Column(name = "DESCRIPTION ")
private String opisZadatka;
#Column(name = "ESTIMATEDDURATIONHOURS")
private Integer trajanje;
#Id
#Column(name = "ID")
#GeneratedValue
private Integer id;
public Task(){
}
And here is the beggining of stack trace:
org.h2.jdbc.JdbcSQLException: Column "USER0_.USERID" not found; SQL statement:
select user0_.ID as ID1_2_0_, user0_.ID as ID1_0_0_, user0_.ID as ID1_0_1_, user0_.FIRSTNAME as FIRSTNAM2_0_1_, user0_.USERNAME as USERNAME3_0_1_, user0_.LASTNAME as LASTNAME4_0_1_, user0_.USERID as USERID5_0_1_, task1_.ID as ID1_2_2_, task1_.DESCRIPTION as DESCRIPT2_2_2_, task1_.ESTIMATEDDURATIONHOURS as ESTIMATE3_2_2_ from TASK.APP_USER user0_ left outer join TASK.PROJECT_TASK task1_ on user0_.USERID=task1_.ID where user0_.ID=? [42122-176]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
at org.h2.message.DbException.get(DbException.java:178)
at org.h2.message.DbException.get(DbException.java:154)
I think that I've posted all relevant info, but if something else is needed, I will gladly add it
Your Task entity has a List<User>, that expects your User to have a #ManyToOne relationship.
However, your table TASK.PROJECT_TASK has an FK to the TASK.APP_USER table. Meaning, the Task has a #ManyToOne relationship to the User, not the other way around.
You mappings are incorrect taking your table descriptions as the source of truth.
The relationship from project to task should be OneToMany and not ManyToOne.
Likewise the relationship from task to project should be ManyToOne and not OneToMany
The relationship between task and user should be ManyToOne and not OneToMany
I am starter in Hibernate & Spring MVC and struggling to find correct solution to my problem.
I have Parent Table (Events)and Child table (Votes). I want to save only child table entry whenever data is received from URL. I am having trouble in mapping relations and putting composite key to work
Following is my structure:
create table Events(
Event_ID int(11) NOT NULL AUTO_INCREMENT,
Event_Name varchar(200) NOT NULL,
Event_options int(1) NOT NULL,
Start_TIME timestamp,
End_time timestamp,
Active_Status int(1),
PRIMARY KEY(Event_ID)
)ENGINE=InnoDB AUTO_INCREMENT=16
;
create table Votes(
Event_ID int(11) NOT NULL,
Voter_MSISDN int(13) NOT NULL,
Vote_Option int(1),
PRIMARY KEY(Event_ID,Voter_MSISDN),
FOREIGN KEY (Event_ID) REFERENCES Events(Event_ID)
)ENGINE=InnoDB AUTO_INCREMENT=16
;
Events.java
#Entity
#Table(name="Events")
public class Events {
#Id
#GeneratedValue
#Column(name = "Event_ID")
private Integer eventId;
#Column(name="Event_Name")
private String eventName;
#Column(name="Event_options")
private Integer eventOptions;
#Column(name="Start_TIME")
private String startTime;
#Column(name = "End_time")
private String End_time;
#Column(name="Active")
private Integer status;
#OneToMany(mappedBy = "Events")
private Set<Votes> votes;
//Setter Getters
}
Votes.java
#Entity
#Table(name="Votes")
public class Votes {
public Votes(){}
#EmbeddedId
private Vote vote;
#Column(name = "Vote_Option")
private int Vote_Option;
#ManyToOne
#JoinColumn(name = "Event_ID")
private Events events;
//setters getters
}
Vote.java for Composite primary key setup through #Embeddable
#Embeddable
public class Vote implements Serializable{
public Vote(){}
#Column(name="Event_ID")
private int Event_ID;
#Column(name="Voter_MSISDN")
private long Voter_MSISDN;
//setter getters
}
controller snippet for Adding Event and adding Vote
#RequestMapping(value="/AddEvent")
#ResponseStatus(value = HttpStatus.OK)
public void AddEvent(#RequestParam(value = "ename", required = true) String ename,
#RequestParam (value = "opt") String opt,
#RequestParam (value = "stime") String start,
#RequestParam (value = "etime") String end,
#RequestParam (value = "status") String active){
Events event = new Events();
event.setEventName(ename);
event.setEventOptions(Integer.parseInt(opt));
event.setStartTime(start);
event.setEnd_time(end);
event.setStatus(Integer.parseInt(active));
userDao.saveEvent(event);
}
#Autowired
private Vote vote;
#Autowired
private Votes votes;
#RequestMapping(value="/AddVote")
#ResponseStatus(value = HttpStatus.OK)
public void AddVote(#RequestParam(value = "eventid",required = true) String eventid,
#RequestParam(value="msisdn") String msisdn,
#RequestParam(value = "opt")String opt){
logger.info("Received parameters from URL "+eventid+" "+msisdn+" "+opt);
vote.setEvent_ID(Integer.parseInt(eventid));
vote.setVoter_MSISDN(Long.parseLong(msisdn));
votes.setVote(vote);
votes.setVote_Option(Integer.parseInt(opt));
userDao.saveVotes(votes);
}
}
DAOImplementation:
#Transactional
public void saveEvent(Events event) {
// TODO Auto-generated method stub
Session session = sessionFactory.getCurrentSession();
session.save(event);
}
#Transactional
public void saveVotes(Votes votes){
Session session = sessionFactory.getCurrentSession();
session.save(votes);
}
The code is working fine whenever Event data is received and Event entry is added.
Not able to code correctly for Vote data.
I want to insert just vote data whenever it is received from url. I have added Composite primary key to make sure unique entry for each event from one user(MSISDN).
Please suggest correct mapping for this model.
Any improvement suggestions are also welcome.
First of all you don't need a composite key for this simple solution.
You have a class:
#Entity
#Table(name="Events")
public class Events {
//....................
#OneToMany(cascade = CascadeType.ALL, mappedBy = "Events")
private Set<Votes> votes = new HashSet<>();
}
Simple just create a method in it which would create a new vote for that event. For e.g.:
public Vote createVote() {
Vote vote = new Vote();
vote.setEvent(this);
votes.add(vote);
return vote;
}
Then in your addVote controller method:
#RequestMapping(value="/AddVote")
#ResponseStatus(value = HttpStatus.OK)
public void AddVote(#RequestParam(value = "eventid",required = true) String eventid,
#RequestParam(value="msisdn") String msisdn,
#RequestParam(value = "opt")String opt){
Event event = userDao.findEvent(eventid);
Vote vote = event.createVote(); //This will create a vote for an event.
vote.set.... //set your stuff.
//It will cascade your vote to an event if you have a cascade sorted correctly as in the example above: cascade = CascadeType.ALL
}
Just make sure you got your transactions right. That's just an idea how it should be done.
I know that there is many question about it but i can not find a good answered for my problem .
I am using Jboss as 7, Spring and Hibernate (4) as JPA 2.0 provider so i have got simple #OneToMany bi-directional relationship :
I have got super class person like that:
#MappedSuperclass
#Inheritance(strategy=InheritanceType.JOINED)
public abstract class Person {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(min = 1, max = 25)
#Pattern(regexp = "[A-Za-z ]*", message = "must contain only letters and spaces")
private String name;
public Person(String name) {
super();
this.name = name;
}
And class Member:
#Entity
#Table(uniqueConstraints = #UniqueConstraint(columnNames = "email"))
public class Member extends Person implements Serializable
{
/** Default value included to remove warning. Remove or modify at will. **/
private static final long serialVersionUID = 1L;
#NotNull
#NotEmpty
#Email
private String email;
#NotNull
#Size(min = 10, max = 12)
#Digits(fraction = 0, integer = 12)
#Column(name = "phone_number")
private String phoneNumber;
#OneToMany(cascade=CascadeType.ALL , mappedBy="member" , fetch=FetchType.EAGER)
private List<Order> orders;
And also class Order:
#Entity
public class Order {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private float price;
#ManyToOne(optional=false)
private Member member;
private String name;
So i think that it is a good configuration, but i test this application in HSQL in memory and i have got error :
Hibernate: alter table Order drop constraint FK48E972E548C740B
2012-09-20 16:25:37 org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: HHH000389: Unsuccessful: alter table Order drop constraint FK48E972E548C740B
2012-09-20 16:25:37 org.hibernate.tool.hbm2ddl.SchemaExport perform
ERROR: Blad skladniowy w wyrazeniu SQL "ALTER TABLE ORDER[*] DROP CONSTRAINT FK48E972E548C740B "; oczekiwano "identifier"
Syntax error in SQL statement "ALTER TABLE ORDER[*] DROP CONSTRAINT FK48E972E548C740B "; expected "identifier"; SQL statement:
alter table Order drop constraint FK48E972E548C740B [42001-165]
And also :
Syntax error in SQL statement "CREATE TABLE ORDER[*] (ID INTEGER GENERATED BY DEFAULT AS IDENTITY, NAME VARCHAR(255), PRICE FLOAT NOT NULL, MEMBER_ID BIGINT NOT NULL, PRIMARY KEY (ID)) "; expected "identifier"; SQL statement:
And my JUnit test failed i dont know what is wrong with this configuration ...
this is my simply junit :
#Test
public void testInsertWithOrder(){
Order order = new Order(20.0f, "first stuff");
Order order2 = new Order(40.0f, "secondary stuff");
List<Order> orders = new ArrayList<Order>();
orders.add(order2);
orders.add(order);
Member member = new Member("Member name", "member23#gmail.com", "2125552141", orders);
memberDao.register(member);
List<Member> members = memberDao.findAllOrderedByName();
Assert.assertNotNull(members);
Assert.assertEquals(1, members.size());
}
Change table name from 'order' to something different, like PersonOrder
In your member in Order Class, there are missing #JoinColumn annotation. Try as below.
#ManyToOne(optional=false)
#JoinColumn(name = "memberId", referencedColumnName = "id")
private Member member;
#CycDemo
I am just figure it out and in my constuctor i now have got :
#OneToMany(cascade=CascadeType.ALL , mappedBy="member" , fetch=FetchType.EAGER)
private List<UOrder> orders = new ArrayList<UOrder>();
public Member(String name, String email, String phoneNumber ,List<UOrder> orders) {
super(name);
this.orders = orders;
this.email = email;
for(UOrder o : orders){
o.setMember(this);
}
this.orders = orders;
}
Ant this is it what i need :)))