I have to create for test reason tables in SQL format.
They should be loaded for the test set up.
And after it, Service and DAO layer should be tested.
I have stuck at creating middle for Entities.
Here is User class:
public class User {
private Integer id;
private String name;
private Calendar birthday;
private String email;
private String role;
private Set<Ticket> bookedTickets = new HashSet<>();
It contains a Set of Tickets.
Here is Ticket POJO:
public class Ticket {
private Integer id;
private Event event;
private Double price;
private User user;
It has User and Event instances.
If Ticket isn't assigned to any User (user == null) => it is free. If is => it is purchased.
Event and Auditorium POJO:
public class Event {
private Integer id;
private String name;
private Double price;
private EventRating eventRating;
private Set<Calendar> eventDateTime;
public class Auditorium {
private Integer id;
private String name;
private Integer numberOfSeats;
private Set<Integer> vipSeats;
Event has Set of available dates, coz some event can be repeated during one day few times.
Getters and setters were omitted at code snippets.
Here is my create-db.sql script:
----------------------
-- Create Users table
----------------------
CREATE TABLE Users (
user_id INTEGER PRIMARY KEY NOT NULL,
user_name VARCHAR(30) NULL,
user_birthday DATETIME NULL,
user_email VARCHAR(30) NULL,
user_role VARCHAR(20) NULL,
user_tickets VARCHAR(100) NULL, -- Here should be collection of objects
);
----------------------
-- Create Events table
----------------------
CREATE TABLE Events (
event_id INTEGER PRIMARY KEY NOT NULL,
event_name VARCHAR(30),
event_price DECIMAL(8,2),
event_rating VARCHAR(30),
event_date DATETIME,
);
---------------------------
-- Create Auditoriums table
---------------------------
CREATE TABLE Auditoriums (
aud_id INTEGER PRIMARY KEY NOT NULL,
aud_name VARCHAR(30),
aud_seats INTEGER,
aud_vip INTEGER,
);
-----------------------
-- Create Tickets table
-----------------------
CREATE TABLE Tickets (
tick_id INTEGER PRIMARY KEY NOT NULL,
event_id VARCHAR(30),
tick_price DECIMAL(8,2),
user_id INTEGER,
);
here is insert-data.sql:
------------------------
-- Populate Users table
------------------------
INSERT INTO Users VALUES (1, 'Garry Potter', '2001-05-01', 'potter#gmail.com', 'admin', NULL);
INSERT INTO Users VALUES (2, 'Ron Weasley', '2000-05-01', 'ron#gmail.com', 'user', NULL);
INSERT INTO Users VALUES (3, 'Germiona Grendjer', '2000-05-01', 'germiona#gmail.com', 'user', NULL);
------------------------
-- Populate Events table
------------------------
INSERT INTO Events (event_id, event_name, event_price, event_rating, event_date)
VALUES (1, 'Green Mile', 60.0, 'high', '2016-02-28');
INSERT INTO Events (event_id, event_name, event_price, event_rating, event_date)
VALUES (2, 'Gone by the wind', 50.0, 'middle', '2016-02-28');
I am using Spring JDBC for working with DB.
How to manage saving Set<Ticket> and Set<Calendar> with SQL script and support their unique as well?
Related
if a java object has a auto-increment ID field, should the Database table field should be auto-increment as well?
for example
public class Company {
private static int countID = 0;
private int companyID;
private String name;
private String email;
private String password;
private List<Coupon> couponsList;
public Company(int companyID, String name, String email, String password, List<Coupon> couponsList) {
this.companyID = companyID+=1;
this.name = name;
this.email = email;
this.password = password;
this.couponsList = couponsList;
}
you can see that the companyID field is generated automatically.
i have created this table in my SQL server
CREATE TABLE `companies` (
`ID` int NOT NULL AUTO_INCREMENT,
`NAME` varchar(200) DEFAULT NULL,
`EMAIL` varchar(200) DEFAULT NULL,
`PASSWORD` varchar(200) DEFAULT NULL,
PRIMARY KEY (`ID`)
how should I connect the Java field (commpanID) to the sql field (ID)?
No. They are different things. Auto-incremented columns in MySQL are not guaranteed to be gapless. Gaps can occur for multiple reasons. The most common are:
Concurrent transactions.
Deletion.
It sounds like you have a unique identifier in Java which is either redundant or an item of data. If the latter, then add it as an additional column.
More likely, though, you might want to reconsider your design, so there is only one auto-incremented value for a given record. I would recommend using the one in the database, because that would apply regardless of how inserts are made into the database.
It isn't compulsory to create and unique id field in the database . You can instead change the table like-->
CREATE TABLE companies (
'COMPANYID' int NOT NULL,
`NAME` varchar(200) DEFAULT NULL,
`EMAIL` varchar(200) DEFAULT NULL,
`PASSWORD` varchar(200) DEFAULT NULL,
PRIMARY KEY (`ID`)
since you are auto incrementing the same the same value twice , it will create some problems.
your ID column will be like this-->
Id|
---
2 |
---
4 |
--
6 |
--
8 |
it will increment the values twice
I have enum class Role. I want to store this values in mysql DB in the table roles.
public enum Role {
ADMIN,
USER,
TRAINER
}
table roles
id role
1 ADMIN
2 USER
3 TRAINER
I use following code for table mapping
#Enumerated(EnumType.ORDINAL)
#Column(name = "role_id")
private Role role;
table users
create TABLE users(
id INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT NOT NULL,
name VARCHAR(30) NOT NULL,
email VARCHAR(20),
password VARCHAR(20),
registered TIMESTAMP DEFAULT now(),
role_id INTEGER UNSIGNED NOT NULL,
enabled BOOL DEFAULT TRUE,
FOREIGN KEY (role_id) REFERENCES roles(id)
)ENGINE=INNODB;
But in Java enum ordinal numbers start from 0, so 0 = ADMIN, 1 = USER, 2 = TRAINER and when i try to set user Role.ADMIN i receive an exception because there are no elements in DB with such number (0).
I want to persist a objects by using JPA in a MYSQL-database. Here ist my create script:
CREATE TABLE toolboxAccount (
idtoolboxAccount INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(30) NOT NULL ,
password_2 VARCHAR(30) NOT NULL ,
PRIMARY KEY(idtoolboxAccount));
CREATE TABLE config (
idconfig INT NOT NULL AUTO_INCREMENT,
toolboxAccount_idtoolboxAccount INTEGER UNSIGNED NOT NULL ,
defaultExportPath VARCHAR(255) NULL ,
PRIMARY KEY(idconfig) ,
INDEX config_FKIndex1(toolboxAccount_idtoolboxAccount),
FOREIGN KEY(toolboxAccount_idtoolboxAccount)
REFERENCES toolboxAccount(idtoolboxAccount)
ON DELETE CASCADE
ON UPDATE CASCADE);
CREATE TABLE connection (
idconnection INT NOT NULL AUTO_INCREMENT,
toolboxAccount_idtoolboxAccount INTEGER UNSIGNED NOT NULL ,
url VARCHAR(255) NULL ,
username VARCHAR(30) NULL ,
password_2 VARCHAR(30) NULL ,
site VARCHAR(30) NULL ,
PRIMARY KEY(idconnection) ,
INDEX connection_FKIndex1(toolboxAccount_idtoolboxAccount),
FOREIGN KEY(toolboxAccount_idtoolboxAccount)
REFERENCES toolboxAccount(idtoolboxAccount)
ON DELETE CASCADE
ON UPDATE CASCADE);
CREATE TABLE export (
idexport INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
connection_idconnection INT NOT NULL ,
nameOfExportZIP VARCHAR(255) NOT NULL ,
PRIMARY KEY(idexport) ,
INDEX export_FKIndex1(connection_idconnection),
FOREIGN KEY(connection_idconnection)
REFERENCES connection(idconnection)
ON DELETE CASCADE
ON UPDATE CASCADE);
The classes are
ToolboxaccountEntity
#Entity
#Table(name = "toolboxaccount", schema = "", catalog = "toolboxtest")
public class ToolboxaccountEntity {
#Id
#GeneratedValue(generator="my_seq")
#SequenceGenerator(name="my_seq",sequenceName="MY_SEQ", allocationSize=1)
private long idtoolboxAccount;
private String username;
private String password_2;
#OneToOne(cascade = CascadeType.PERSIST)
private ConfigEntity configEntity;
#OneToMany(cascade = CascadeType.PERSIST)
private List<ConnectionEntity> connections;
public List<ConnectionEntity> getConnections() {
return connections;
}
public void setConnections(List<ConnectionEntity> connections) {
this.connections = connections;
}
...
ConnectionEnity
#Entity
#Table(name = "connection", schema = "", catalog = "toolboxtest")
public class ConnectionEntity {
#Id
#GeneratedValue(generator="my_seq")
#SequenceGenerator(name="my_seq",sequenceName="MY_SEQ", allocationSize=1)
private long idconnection;
private String url;
private String username;
private String password_2;
private String site;
#Column(name = "idconnection")
public long getIdconnection() {
return idconnection;
}
public void setIdconnection(int idconnection) {
this.idconnection = idconnection;
}
...
The persisting of ToolboxAccountEntity works but when I add a ConnectionEntity I get following error:
Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`toolboxtest`.`connection`, CONSTRAINT `connection_ibfk_1` FOREIGN KEY (`toolboxAccount_idtoolboxAccount`) REFERENCES `toolboxaccount` (`idtoolboxAccount`) ON DELETE CASCADE ON UPDATE CASCADE)
Error Code: 1452
Call: INSERT INTO toolboxtest.connection (PASSWORD_2, SITE, URL, USERNAME) VALUES (?, ?, ?, ?)
bind => [4 parameters bound]
2 things:
1) If you want to make a insert operation, make sure that the record doesnt exists in the Database.
2) If you want to make an update operation, make sure that the record exist in the database.
3) Remember that the records has to be well relationships, primary key, foreign key.
That kind of error, is very common when a record already exists.
Regards! Tell us if you correct your issue
Here is bean class,
#Entity
#Table(name="hlatlng")
public class HistoryLatitudeBean {
#Id
#GeneratedValue
#Column(name = "id")
private int id;
#Column(name="vehicleno")
private int vehicleno;
#Column(name="lat")
private String lat;
#Column(name="lng")
private String lng;
#Column(name="status")
private String status;
#Column(name="rdate")
private Date rdate;
#Column(name="rtime")
private Date rtime;
//getter setter,
}
In Hibernate method I am writing,
Map<String, Object> parameterNameAndValues = new HashMap<String, Object>();
parameterNameAndValues.put("vehicleno", 12);
parameterNameAndValues.put("frmdate", frmDate);
parameterNameAndValues.put("todate", toDate);
hql= "from HistoryLatitudeBean where vehicleno=:vehicleno and rdate BETWEEN :frmdate and :todate";
Query query =session.createQuery(hql);
/*query.setParameter("vehicleno", 12);
query.setParameter("frmdate", frmDate);
query.setParameter("todate", toDate);*/
for (Entry<String, Object> e : parameterNameAndValues.entrySet()) {
query.setParameter(e.getKey(), e.getValue());
}
List<HistoryLatitudeBean> groupList = (List<HistoryLatitudeBean>)query.list();
//Here groupList contains null
for(HistoryLatitudeBean arr : groupList){
vehicleHistoryList.add(arr);
System.out.println("List :"+arr.getLat());
}
transaction.commit();
Problem is query.list() method returns null.
The same query I am trying in mysql db as,
SELECT * FROM hlatlng WHERE vehicleno='12' AND rdate BETWEEN '2014-01-01' AND '2014-09-01';
and my table structure is like this,
CREATE TABLE `hlatlng` (
`vehicleno` int(40) DEFAULT NULL,
`lat` varchar(40) DEFAULT NULL,
`lng` varchar(40) DEFAULT NULL,
`status` varchar(40) DEFAULT NULL,
`rdate` date DEFAULT NULL,
`rtime` date DEFAULT NULL,
`id` int(40) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
It gives me 3 rows. I am not getting what is wrong in my code , can any one help me in this please.
The Date in java will have the time part associated with it. If our data is only on dates, we need to trim the time part.
Adding the #Type(type="date") will take care of this while sending it to the database.
I tried to find a reference, unfortunately I could not find anything.
I've encountered a strange error with JPA that is not persistence provider specific. I'm using JPA 2.0 and I'm using a generated schema.
In short: The generated schema includes a join table with three columns, but the generated insert statements treat this table as if it had only two columns.
Here are the mappings:
#Entity
#Table( name = "Game" )
public class MatchEntity implements Match, Serializable {
#Id
#GeneratedValue( strategy = GenerationType.AUTO )
private Long id;
#ManyToOne( targetEntity = ClubEntity.class )
private Club homeTeam;
#ManyToOne( targetEntity = ClubEntity.class )
private Club awayTeam;
#ManyToMany( targetEntity = PlayerEntity.class )
private Collection<Player> homeTeamPlayers;
#ManyToMany( targetEntity = PlayerEntity.class )
private Collection<Player> awayTeamPlayers;
private String location;
#Temporal( value = TemporalType.DATE )
#Column( name = "Match_Date" )
private Date date;
/* constructor, getters and setters follow */
}
#Entity
#Table( name = "Club" )
public class ClubEntity implements Club, Serializable {
#Id
#GeneratedValue( strategy = GenerationType.AUTO )
private Long id;
private String name;
#OneToMany( fetch = FetchType.EAGER, targetEntity = PlayerEntity.class,
mappedBy = "club" )
private Collection<Player> players = new ArrayList<Player>();
private String fieldName;
private Boolean archived;
/* constructor, getters and setters follow */
}
#Entity
#Table( name = "PLAYER" )
public class PlayerEntity implements Player, Serializable {
#Id
#GeneratedValue( strategy = GenerationType.AUTO )
private Long id;
private String firstName;
private String surname;
#Temporal( value = TemporalType.DATE )
private Date birthDate;
#Column( name = "pos" )
#Enumerated( EnumType.ORDINAL )
private Position position;
private Integer number;
private Boolean archived;
#ManyToOne( targetEntity = ClubEntity.class, fetch = FetchType.EAGER )
private Club club;
/* constructor, getters and setters follow */
}
From these mappings, the following schema gets created:
create table Club (id bigint generated by default as identity (start with 1), archived bit, fieldName varchar(255) not null, name varchar(255) not null, primary key (id))
create table Game (id bigint generated by default as identity (start with 1), Match_Date date, location varchar(255), awayTeam_id bigint, homeTeam_id bigint, primary key (id))
create table Game_PLAYER (Game_id bigint not null, homeTeamPlayers_id bigint not null, awayTeamPlayers_id bigint not null)
create table PLAYER (id bigint generated by default as identity (start with 1), archived bit, birthDate date, firstName varchar(255) not null, number integer, pos integer, surname varchar(255) not null, club_id bigint, primary key (id))
alter table Game add constraint FK21C0123B2A3B9E foreign key (homeTeam_id) references Club
alter table Game add constraint FK21C012F5972EAF foreign key (awayTeam_id) references Club
alter table Game_PLAYER add constraint FK267CF3AE6AE1D889 foreign key (Game_id) references Game
alter table Game_PLAYER add constraint FK267CF3AED51EDECF foreign key (homeTeamPlayers_id) references PLAYER
alter table Game_PLAYER add constraint FK267CF3AE6CBE869E foreign key (awayTeamPlayers_id) references PLAYER
alter table PLAYER add constraint FK8CD18EE13F2C6C64 foreign key (club_id) references Club
This line is important - this is the join table.
create table Game_PLAYER (Game_id bigint not null, homeTeamPlayers_id bigint not null, awayTeamPlayers_id bigint not null)
When I try to persist the Game entity (MatchEntity.java), this happens:
insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?)
Hibernate: insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?)
binding '2' to parameter: 1
binding '1' to parameter: 2
reusing prepared statement
insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?)
Hibernate: insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?)
binding '2' to parameter: 1
binding '2' to parameter: 2
done inserting collection: 2 rows inserted
Inserting collection: [football.model.entities.MatchEntity.homeTeamPlayers#2]
Executing batch size: 2
about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
Could not execute JDBC batch update [insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?)]
JPA tries to insert two rows to the join table, each affecting only two columns of the three.
What I have tried:
Getting rid of the interfaces in the mappings altogether
Defining an explicit join table
Using OpenJPA instead of Hibernate
Neither did resolve the problem.
edit: code for eager fetching:
#Transactional(readOnly = true)
public Collection<Match> findAll() {
em.createQuery("SELECT m FROM MatchEntity m "
+ "JOIN FETCH m.homeTeamPlayers", MatchEntity.class).getResultList();
List<MatchEntity> rList = em.createQuery("SELECT m FROM MatchEntity m "
+ "JOIN FETCH m.awayTeamPlayers", MatchEntity.class).getResultList();
Collection<Match> result = new ArrayList<Match>( rList );
return result;
}
Perhaps you need different join tables for homeTeamPlayers and awayTeamPlayers:
#ManyToMany( targetEntity = PlayerEntity.class )
#JoinTable(name = "Game_HomeTeamPlayers")
private Collection<Player> homeTeamPlayers;
#ManyToMany( targetEntity = PlayerEntity.class )
#JoinTable(name = "Game_AwayTeamPlayers")
private Collection<Player> awayTeamPlayers;