Fetch the data between Two date in Hibernate Jave with MySQL? - java

Am new to Java server side and i creating JSON Links using Jersey library. In my project am Using Hibernate to Get the data from MySQL database. I want to fetch the data between two dates in MySQL.But Query is Not Working properly.
MySQL Table
CREATE TABLE `order_headers` (
`bill_number` int(10) NOT NULL AUTO_INCREMENT,
`order_number` varchar(100) DEFAULT NULL,
`table_number` varchar(20) NOT NULL,
`payment_type` varchar(20) DEFAULT NULL,
`discount` double NOT NULL,
`payment_status` varchar(30) DEFAULT NULL,
`order_status` varchar(20) DEFAULT NULL,
`order_date` date NOT NULL,
`grand_total` decimal(7,2) NOT NULL,
`upt_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`bill_number`)
)
Depends upon the order_date column in the table to fetch data.
Hibernate Annotation Class
#Entity
#Table(name = "order_headers")
public class Order_headers {
#Id #GeneratedValue
#Column(name = "bill_number")
private String bill_number;
#Column(name = "order_number")
private String order_number;
#Column(name = "order_value")
private double order_value;
//format YYYY-mm-dd
#Column(name = "order_date")
private String order_date;
//All other Variables and Getter Setters
}
Query Used to fetch data in JAVA
//Query i used
/*FROM Order_headers oh WHERE oh.merchant_code = :merchant_code AND oh.branch_code = :branch_code AND DATE_FORMAT(oh.order_date,'%d-%m-%Y') >= :from_date AND DATE_FORMAT(oh.order_date,'%d-%m-%Y') <= :to_date ORDER BY DATE_FORMAT(oh.order_date,'%d-%m-%Y') ASC*/
Query query = session.createQuery("FROM Order_headers oh WHERE oh.merchant_code = :merchant_code AND oh.branch_code = :branch_code AND DATE_FORMAT(oh.order_date,'%d-%m-%Y') >= :from_date AND DATE_FORMAT(oh.order_date,'%d-%m-%Y') <= :to_date ORDER BY DATE_FORMAT(oh.order_date,'%d-%m-%Y') ASC");
query.setParameter( "merchant_code", merchant_code );
query.setParameter( "branch_code", branch_code );
query.setParameter( "from_date", from_date );
query.setParameter( "to_date", to_date );
In table have data till 22-06-2015
I check with two condition:
When i pass these parameters merchant_code=1&branch_code=1&from_date=10-02-2015&to_date=16-07-2015 it fetch all the data between two dates.
When i pass these parameters merchant_code=1&branch_code=1&from_date=10-02-2015&to_date=15-07-2015 this not even a single data.When i give date from 01-07-2015 to 15-07-2015 in to_date parameter same problem continues.
Am search it in Google all of them give same query what i used,but i am not able find out the issue.Can any one know help me to solve this issue.

Try to use Between
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String fromDate= format.parse(from_date);
String toDate= format.parse(to_date);
Query query = session.createQuery("FROM Order_headers oh WHERE oh.merchant_code = :merchant_code AND oh.branch_code = :branch_code AND oh.order_date BETWEEN fromDate AND toDate");
query.setParameter( "fromDate", fromDate);
query.setParameter( "toDate", toDate );

Related

Spring Hibernate SQL Server - problem in updating columns

I get the below error while not updating the mentioned column at all. I only update two another columns that one of them is used to compute the column "Available".
The column "Available" cannot be modified because it is either a computed column or is the result of a UNION operator.
I also used native query (as below) to be sure that there is no problem during translating hql to sql, but the problem still exists
query = session.createQuery("update Retail.Account SET Balance = Balance + :Amount, RowVersion = RowVersion + 1 WHERE RowVersion = :RowVersion AND Id = :Id")
Here is my model(table) definition:
#Entity
#Table(name = "Account", schema = "Retail")
public class Account {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "Id")
public Integer Id;
// ..... some attributes
#Column(name = "Balance")
public BigDecimal Balance; // the column that I want to update
#Column(name = "Available")
public BigDecimal Available;// the computed column in my error
// ......
#Version
#Column(name = "RowVersion")
public Long RowVersion;
}
My hibernate Configuration is as below:
hibernate.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.url=########
hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.username=**************
hibernate.password=**************
hibernate.hbm2ddl.auto=none
hibernate.setConnectionCachingEnabled=true
hibernate.show_sql=false
hibernate.format_sql=true
Also my table definition in SQL Server is as below:
CREATE TABLE [Retail].[Account](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CustomerId] [int] NOT NULL,
[AccountTypeId] [int] NOT NULL,
[OpeningDate] [datetime] NOT NULL,
[StatusId] [int] NOT NULL,
[Balance] [decimal](18, 2) NOT NULL,
[Credit] [decimal](18, 2) NOT NULL,
[Blocked] [decimal](18, 2) NULL,
[Available] AS (([Balance]+[Credit])-[Blocked]),
[RowVersion] [bigint] NOT NULL,
CONSTRAINT [PK_Account] PRIMARY KEY CLUSTERED
([Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
My problem was solved when I added #Generated tag as below:
#Generated( value = GenerationTime.ALWAYS )
#Column(name = "Available")
public BigDecimal Available;
But I can't understand why ?!!! (because it does not seem to be mandatory specially when I use native query)

Persist entity using Java Hibernate API and update if already exists

Have the following table and Java Entity:
CREATE TABLE search_terms (
id int(100) NOT NULL AUTO_INCREMENT,
term varchar(255) NOT NULL DEFAULT '',
last_search_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
search_count int(100) NOT NULL DEFAULT '0',
user_email varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
public class SearchTerms implements Serializable {
private Long id;
private String term;
private Timestamp lastSearchDate;
private int searchCount;
private String userEmail;
Want to persist java objects of the given type into the table above.
Example:
List<String> searchTerms = Arrays.asList("test1", "test2", "test3");
saveSearchParams(searchTerms);
If any of those terms exist in the table, I want to increment searchCount else save as a new row.
Need to use JPA.em().merge(o) etc and not have sql insert/update queries
Added the following constant on the two columns but JPA.em().merge(o) keeps inserting new rows.
#Table(name="search_terms", uniqueConstraints= { #UniqueConstraint(columnNames = {"term", "user_email"})})
saveSearchParams() {
searchTerms.forEach(o -> {
SearchTerms term = new SearchTerms();
term.setSearchCount(1);
term.setTerm((String) o);
term.setUserEmail(email);
jpaApi.em().merge(term);
});
}
Any help on or documentation is appreciated.
Merge can both update and insert, but you should check if the object exists in DB to see if you have to set the counter to one or add one to it, for this you will have to throw a query for each element.
try this:
saveSearchParams() {
searchTerms.forEach(o -> {
//search for example by id or in any other way
SearchTerms term = jpaApi.em().find(SearchTerms.class, o.getId());
if (term == null){
term = new SearchTerms();
term.setSearchCount(1);
}else{
term.setSearchCount(term.getSearchCount()+1);
}
term.setTerm((String) o);
term.setUserEmail(email);
jpaApi.em().merge(term);
});
}

Get only the latest status by MAX function for each Application using WHERE clausule instead of ORDER BY

I would like to obtain the same result of query using WHERE instead of GROUP BY. I have applications and each application has statuses with date. I need to return applications with their latest status date.
My query with ORDER BY: (the result is correct)
select a.guid, MAX(s.request_time) as last_request_time
from public.applications_status s inner join public.applications a on a.guid = s.guid_application
group by a.guid ;
result:
guid |last_request_time |
------------------------------------|-------------------|
330d32d5-2496-4cce-9d11-29e59333766a|2020-07-22 13:06:25|
5b46cda9-b954-4d8b-82cf-f1d83f77b175|2020-07-22 13:07:25|
34071189-ab3d-47ff-9ee1-aca6fa806bc9|2020-08-03 10:45:15|
a8961058-a6ee-4d71-b325-9aca83b22237|2020-08-03 10:45:39|
ff98695f-e1a8-439e-8a6c-7991348b6cd7|2020-07-29 14:38:18|
I try this but it return me only the one application with latest status date:
select a.guid, s.request_time
from public.applications_status s inner join public.applications a on a.guid = s.guid_application
where request_time = (select MAX(applications_status.request_time) from applications_status );
result:
guid |request_time |
------------------------------------|-------------------|
a8961058-a6ee-4d71-b325-9aca83b22237|2020-08-03 10:45:39|
Applications table
CREATE TABLE public.applications (
id bigserial NOT NULL,
guid varchar(40) NOT NULL,
"name" varchar(60) NOT NULL,
latest_status_date timestamp NULL,
latest_status bool NOT NULL,
id_production bigserial NOT NULL,
CONSTRAINT applications_guid_key UNIQUE (guid),
CONSTRAINT applications_pkey PRIMARY KEY (id),
CONSTRAINT uk_gtuqgycxk8ulkir3io2p49yn1 UNIQUE (guid),
CONSTRAINT fkaid_prod FOREIGN KEY (id_production) REFERENCES productions(id) ON DELETE CASCADE
);
Applications_status table
CREATE TABLE public.applications_status (
id bigserial NOT NULL,
status bool NOT NULL,
guid_application varchar(50) NOT NULL,
log varchar(200) NULL,
request_time timestamp NOT NULL,
CONSTRAINT status_pkey PRIMARY KEY (id),
CONSTRAINT fkaguid_application FOREIGN KEY (guid_application) REFERENCES applications(guid) ON UPDATE CASCADE ON DELETE CASCADE
);
Why I need this way? I try to return Applications with their latest status in Spring Boot using #Where annotation in #OneToMany relation in Entity.
#OneToMany(cascade = CascadeType.ALL, mappedBy = "application", fetch = LAZY)
#JsonManagedReference
#Where(clause = "request_time = (SELECT MAX(applications_status.request_time) FROM applications_status )")
#OrderBy("requestTime DESC")
private List<ApplicationStatus> applicationStatuses;
I also try to use #BatchSize(size = 1) but it doesn't work.
The question is tagged both "sql" and "postgres", so this is a Postgres solution.
Use distinct on:
select distinct on (a.guid) a.*, s.*
from public.applications_status s inner join
public.applications a
on a.guid = s.guid_application
order by a.guid, s.request_time desc;
distinct on is a very handy Postgres extension that returns one row (the "first" row) for each group in the parentheses. The particular row is based on the order by.
Through trial and error, I found a solution:
SQL query:
select a.guid, s.request_time
from public.applications_status s inner join public.applications a on a.guid = s.guid_application
where request_time = (select MAX(applications_status.request_time)
from applications_status
where applications_status.guid_application = s.guid_application );
Spring-Boot:
#OneToMany(cascade = CascadeType.ALL, mappedBy = "application", fetch = LAZY)
#JsonManagedReference
#Where(clause = "request_time = (SELECT MAX(applications_status.request_time) FROM applications_status where guid_application = applications_status.guid_application )")
#OrderBy("requestTime DESC")
private List<ApplicationStatus> applicationStatuses;

Not getting MySQL SELECT LPAD() in ResultSet

I am trying to select multiple columns from different tables in MySQL.
MySQL:
CREATE TABLE IF NOT EXISTS movie(
movie_id TINYINT(3) UNSIGNED AUTO_INCREMENT,
movie_title VARCHAR(255) NOT NULL,
movie_genre VARCHAR(255) NOT NULL,
movie_rating ENUM('G', 'PG', 'R-13', 'R-16', 'R-18', 'PENDING') NOT NULL,
movie_cast VARCHAR(255) NOT NULL,
movie_runtime TINYINT(3) UNSIGNED NOT NULL,
movie_poster VARCHAR(255) NOT NULL,
PRIMARY KEY(movie_id)
);
CREATE TABLE IF NOT EXISTS mall(
mall_id VARCHAR(255),
mall_name VARCHAR(255) NOT NULL,
PRIMARY KEY(mall_id)
);
CREATE TABLE IF NOT EXISTS schedule(
schedule_id TINYINT(3) UNSIGNED AUTO_INCREMENT,
movie_id TINYINT(3) UNSIGNED NOT NULL,
mall_id VARCHAR(255) NOT NULL,
schedule_cinema TINYINT(2) UNSIGNED NOT NULL,
schedule_price DECIMAL(5, 2) NOT NULL,
schedule_date DATE NOT NULL,
schedule_time TIME NOT NULL,
schedule_seats TINYINT(2) UNSIGNED NOT NULL,
PRIMARY KEY(schedule_id),
FOREIGN KEY(movie_id) REFERENCES movie(movie_id),
FOREIGN KEY(mall_id) REFERENCES mall(mall_id)
ON DELETE CASCADE
ON UPDATE CASCADE
)ENGINE=INNODB;
CREATE TABLE IF NOT EXISTS transaction(
transaction_id SMALLINT(5) UNSIGNED AUTO_INCREMENT,
user_id VARCHAR(255) NOT NULL,
schedule_id TINYINT(3) UNSIGNED NOT NULL,
transaction_date DATE NOT NULL,
PRIMARY KEY(transaction_id),
FOREIGN KEY(user_id) REFERENCES user(user_id),
FOREIGN KEY(schedule_id) REFERENCES schedule(schedule_id)
ON DELETE CASCADE
ON UPDATE CASCADE
)ENGINE=INNODB;
I tested this query directly in XAMPP MySQL and it returned all desired columns. The transaction_id is also left-padded as intended.
SELECT SQL:
SELECT LPAD(transaction_id, 5, 0), transaction_date, movie_title, schedule_price, mall_name, schedule_cinema, schedule_date, schedule_time FROM transaction INNER JOIN schedule ON transaction.schedule_id = schedule.schedule_id INNER JOIN movie ON schedule.movie_id = movie.movie_id INNER JOIN mall ON schedule.mall_id = mall.mall_id WHERE user_id = 'admin';
This method was supposed to return a list of History objects, using the above SELECT SQL.
public List<History> getTransactionHistory(String currentUserId){
History history;
List<History> historyList = new ArrayList<History>();
sql = "SELECT LPAD(transaction_id, 5, 0), transaction_date, movie_title, schedule_price, "
+ "mall_name, schedule_cinema, schedule_date, schedule_time FROM transaction "
+ "INNER JOIN schedule ON transaction.schedule_id = schedule.schedule_id "
+ "INNER JOIN movie ON schedule.movie_id = movie.movie_id "
+ "INNER JOIN mall ON schedule.mall_id = mall.mall_id "
+ "WHERE user_id = ?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, currentUserId);
rs = ps.executeQuery();
while(rs.next()) {
history = HistoryAssembler.getInstance(
rs.getString("transaction_id"),
rs.getDate("schedule_date"),
rs.getString("movie_title"),
rs.getBigDecimal("schedule_price"),
rs.getString("mall_name"),
rs.getInt("schedule_cinema"),
rs.getDate("schedule_date"),
rs.getTime("schedule_time")
);
System.out.println(history.getTransactionId());
historyList.add(history);
}
} catch(SQLException se) {
se.printStackTrace();
}
return historyList;
}
History (Bean):
public class History {
private String transactionId;
private Date transactionDate;
private String movieTitle;
private BigDecimal schedulePrice;
private String mallName;
private Integer scheduleCinema;
private Date scheduleDate;
private Time scheduleTime;
// getters and setters
}
HistoryAssembler:
public static History getInstance(String transactionId, Date transactionDate, String movieTitle, BigDecimal schedulePrice,
String mallName, Integer scheduleCinema, Date scheduleDate, Time scheduleTime) {
History history = new History();
history.setTransactionId(transactionId);
history.setTransactionDate(transactionDate);
history.setMovieTitle(movieTitle);
history.setSchedulePrice(schedulePrice);
history.setMallName(mallName);
history.setScheduleCinema(scheduleCinema);
history.setScheduleDate(scheduleDate);
history.setScheduleTime(scheduleTime);
return history;
}
However, I am getting a java.sql.SQLException: Column 'transaction_id' not found, when I do have the said column.
From what I understand, LPAD() should return a String, so that is why I set the transactionId in the bean as such.
Your assistance is much appreciated.
After the "LPAD" function the column name is changed and "XAMPP" fixed for you. You must put alias in this query after "LPAD(transaction_id, 5, 0) as transaction_id".
SELECT LPAD(transaction_id, 5, 0) as transaction_id
, transaction_date
, movie_title
, schedule_price
, mall_name
, schedule_cinema
, schedule_date
, schedule_time
FROM transaction INNER JOIN schedule ON transaction.schedule_id = schedule.schedule_id
INNER JOIN movie ON schedule.movie_id = movie.movie_id
INNER JOIN mall ON schedule.mall_id = mall.mall_id
WHERE user_id = 'admin';

How to specify a field, so that when we query, using Joda LocalDate or LocalDateTime value for the field, it is mapped to same column?

I have a postgres database that has a table "draft" containing a column set_up_time, saved as a timestamp:
#Column(nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
LocalDateTime setUpTime;
For certain reasons I need to keep this structure as it is. However I am expecting database queries searching for records, for setUpTime as LocalDateTime and setUpTime as LocalDate. How can I map it in a way, that hibernate queries the database with both these types for setUpTime, and returns the results accordingly?
The schema I am using is :
"create table draft (dtype varchar(31) not null, id int8 not null, creation_time timestamp not null, cust_ord varchar(1), description varchar(255), amount decimal(12, 2), user varchar(6), txn_time timestamp, text1from varchar(36), text2from varchar(36), text3from varchar(36), primary key (id))"
What you can do is write your queries like this:
public void findDrafts(LocalDate targetDate) {
final Query query = entityManager.createQuery(
"from Draft where setUpTime => :beginOfDay and setUpTime < :beginOfNextDay");
query.setParameter("beginOfDay", targetDate.toDateTimeAtStartOfDay().toLocalDateTime());
query.setParameter("beginOfNextDay", targetDate.plusDays(1).toDateTimeAtStartOfDay().toLocalDateTime());
return query.getResultList();
}

Categories