Can't alter table(blocked) while hibernate is connected to mysql server - java

I have a table name test;
mysql> desc test;
+--------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| name | varchar(255) | YES | | NULL | |
| gendar | varchar(255) | YES | | NULL | |
+--------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> select * from test;
+----+------+--------+
| id | name | gendar |
+----+------+--------+
| 0 | John | male |
+----+------+--------+
1 row in set (0.00 sec)
And have a hibernate Entity like this:
#Entity
#Table(name = "test",schema = "", catalog = "mydb")
public class TestEntity {
private int id;
private String name;
private String gendar;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "gendar")
public String getGendar() {
return gendar;
}
public void setGendar(String gendar) {
this.gendar = gendar;
}
}
The hibernate.xml is:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/mydb</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">test</property>
<property name="connection.password">test</property>
<mapping class="me.armnotstrong.sql.TestEntity" />
<!-- DB schema will be updated if needed -->
<!-- <property name="hbm2ddl.auto">update</property> -->
</session-factory>
</hibernate-configuration>
The hibernate session is generated by this factory class:
public class HBSession {
private static final SessionFactory ourSessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() throws HibernateException {
Session session = ourSessionFactory.openSession();
return session;
}
}
And I just add a user to the db by this
public class TestHb {
public static void main(String[] argvs){
Session session = HBSession.getSession();
TestEntity testEntity = new TestEntity();
testEntity.setName("John");
testEntity.setGendar("male");
Transaction tx = session.beginTransaction();
session.save(testEntity);
tx.commit();
session.close();
}
}
After run the TestHB code above to add a user to mysql, the session seemed to just hang there, and won't colse, diagnose using netstat -nap just proved my guess, but it's ok, I think. In fact, this just simulate the condition of a long connection to the db in the product environment which hibernate make.
The question comes that, when I alter the table when hibernate connection still there, The mysql client just blocked. and wont do the alter action as presumed unless I restart the mysql service. and in product environment, after restart the mysql service, one thing come after another, The hibernate app will not work anymore.
So what should I do to alter the table and keep my hibernate also working?
as required by #Florent, here is some addition info come out of command SHOW FULL PROCESSLIST and SHOW OPEN TABLES;
mysql> show open tables;
+----------+----------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+----------+--------+-------------+
| test | merchant | 0 | 0 |
| test | test | 0 | 0 |
| test | orders | 0 | 0 |
| test | product | 0 | 0 |
| test | codes | 0 | 0 |
+----------+----------+--------+-------------+
5 rows in set (0.02 sec)
mysql> show full processlist;
+-----+--------+-----------------+--------+---------+------+-------+-----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+--------+-----------------+--------+---------+------+-------+-----------------------+
| 42 | test | localhost:35790 | test | Sleep | 4 | | NULL |
| 43 | test | localhost:35801 | test | Sleep | 4 | | NULL |
| 44 | test | localhost:35802 | test | Sleep | 4 | | NULL |
| 45 | test | localhost:35803 | test | Sleep | 4 | | NULL |
| 46 | test | localhost:35804 | test | Sleep | 4 | | NULL |
| 157 | test | localhost:51516 | test | Sleep | 174 | | NULL |
| 161 | test | localhost:53988 | test | Sleep | 174 | | NULL |
| 180 | test | localhost:58501 | test | Sleep | 174 | | NULL |
| 192 | test | localhost:47228 | test | Sleep | 7217 | | NULL |
| 193 | test | localhost:49372 | test | Sleep | 4485 | | NULL |
| 196 | test | localhost | test | Sleep | 9256 | | NULL |
| 197 | test | localhost | test | Sleep | 4555 | | NULL |
| 198 | test | localhost:42411 | test | Sleep | 4485 | | NULL |
| 200 | test | localhost | test | Query | 0 | NULL | show full processlist |
+-----+--------+-----------------+--------+---------+------+-------+-----------------------+
14 rows in set (0.00 sec)

Related

How can I insert fields into the mysql database but skip a column or two if it's a duplicate?

I'm reading line by line from a file then inserting the details in a mysql database. But the issue is that some lines do not contain a field I called natted ip and port. I loop through the file then insert into db. However the issue is that because not every row contains natted ip and port, I need the database to skip these two columns when inserting into the table where they do not appear but insert the rest and not duplicate. How can I ensure that?
public static void readData() throws ClassNotFoundException, SQLException{
File fileName = new File(FILE);
try(Scanner input = new Scanner(fileName) ){
String firstLine, secondLine, thirdLine;
firstLine = input.nextLine();
secondLine = input.nextLine();
String[] secondString = secondLine.split(" ");
for(String string: secondString){
timestamp = secondString[0]+" "+secondString[1]; //to be inserted
timezone = secondString[2]; //to be inserted
}
thirdLine = input.nextLine();
String[] thirdString = thirdLine.split(":");
for(String string: thirdString){
session = thirdString[1].trim(); //to be inserted
}
while(input.hasNextLine()){
String line;
line = input.nextLine();
String[] cdr_string = line.split(" ");
for(String string:cdr_string){
type = cdr_string[1].trim(); //to be inserted
internalIP_and_port = cdr_string[8];
destinationIP_and_port = cdr_string[10].trim();
}
if(internalIP_and_port.contains("[")){
String[] splitIPs = internalIP_and_port.split(Pattern.quote("["));
for(String string:splitIPs){
internalIP_and_port = splitIPs[0].trim();
nattedIP_and_port = splitIPs[1].trim();
nattedIP_and_port = nattedIP_and_port.substring(0, nattedIP_and_port.length() -1);
}
String[] splitIP_and_port = nattedIP_and_port.split(":");
for(String string:splitIP_and_port){
natted_ip = splitIP_and_port[0].trim(); //to be inserted
natted_port = splitIP_and_port[1].trim(); //to be inserted
}
// System.out.println(natted_ip);
}
String[] split_internal_IP_and_port = internalIP_and_port.split(":");
for(String string : split_internal_IP_and_port){
internal_ip = split_internal_IP_and_port[0].trim(); //to be inserted
internal_port = split_internal_IP_and_port[1].trim(); //to be inserted
}
String[] split_destination_IP_and_port = destinationIP_and_port.split(":");
for(String string : split_destination_IP_and_port){
destination_ip = split_destination_IP_and_port[0].trim(); //to be inserted
destination_port = split_destination_IP_and_port[1].trim(); //to be inserted
}
saveData();
}
}catch(IOException ex){
System.out.println(ex);
}
File log_done = new File(FILE_DONE);
fileName.renameTo(log_done);
fileName.delete();
}
private static void saveData() throws ClassNotFoundException, SQLException{
Connection con = connect();
PreparedStatement stmt = con.prepareStatement("INSERT INTO decoder(type, internal_ip, internal_port, natted_ip, natted_port, destination_ip, destination_port, session, timestamp, timezone, filename) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setString(1, type);
stmt.setString(2, internal_ip);
stmt.setString(3, internal_port);
stmt.setString(4, natted_ip);
stmt.setString(5, natted_port);
stmt.setString(6, destination_ip);
stmt.setString(7, destination_port);
stmt.setString(8, session);
stmt.setString(9, timestamp);
stmt.setString(10, timezone);
stmt.setString(11, FILENAME);
stmt.executeUpdate();
}
public static Connection connect() throws ClassNotFoundException, SQLException{
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}```
I'm reading from this file:
udp VPN: public --> public 41.72.118.178:56620 --> 103.10.116.19:51130
https VPN: public --> public 10.65.19.224:46765[165.56.53.149:15674] --> 31.13.75.36:443
tcp VPN: public --> public 35.212.240.3:34533 --> 41.72.96.58:20792
dns VPN: public --> public 10.65.179.189:12718 --> 165.56.45.2:53
https VPN: public --> public 10.65.145.37:34490[165.56.53.161:38013] --> 185.60.219.9:443
https VPN: public --> public 10.65.14.63:43956[165.56.53.178:27552] --> 216.58.223.106:443
https VPN: public --> public 10.66.32.44:37573[165.56.53.141:29821] --> 185.60.219.33:443
udp VPN: public --> public 172.21.242.243:10188[41.72.123.88:55777] --> 119.3.74.66:10327
http VPN: public --> public 172.21.218.82:65167[41.72.121.132:46765] --> 5.45.58.214:80
https VPN: public --> public 10.66.118.81:52792[165.56.53.185:46319] --> 104.82.200.59:443
udp VPN: public --> public 76.64.76.78:13114 --> 41.72.108.238:34835
I want it to show like this:
+----+----------+----------------+---------------+---------------+------------
| id | type | internal_ip | internal_port | natted_ip | natted_port
+----+----------+----------------+---------------+---------------+------------
| 1 | udp | 41.72.118.178 | 56620 | NULL | NULL |
| 2 | https | 10.65.19.224 | 46765 | 165.56.53.149 | 15674 |
| 3 | tcp | 35.212.240.3 | 34533 | NULL | NULL |
| 4 | dns | 10.65.179.189 | 12718 | NULL | NULL |
| 5 | https | 10.65.145.37 | 34490 | 165.56.53.161 | 38013 |
| 6 | https | 10.65.14.63 | 43956 | 165.56.53.178 | 27552 |
| 7 | https | 10.66.32.44 | 37573 | 165.56.53.141 | 29821 |
| 8 | udp | 172.21.242.243 | 10188 | 41.72.123.88 | 55777 |
| 9 | http | 172.21.218.82 | 65167 | 41.72.121.132 | 46765 |
| 10 | https | 10.66.118.81 | 52792 | 165.56.53.185 | NULL |
| 11 | udp | 76.64.76.78 | 13114 | NULL | NULL |
| 12 | https | 10.66.81.19 | 34736 | 165.56.53.81 | 29021 |
| 13 | tcp | 10.66.18.62 | 55976 | 165.56.53.233 | 62585
And not like this:
+----+----------+----------------+---------------+---------------+------------
| id | type | internal_ip | internal_port | natted_ip | natted_port
+----+----------+----------------+---------------+---------------+------------
| 1 | udp | 41.72.118.178 | 56620 | NULL | NULL |
| 2 | https | 10.65.19.224 | 46765 | 165.56.53.149 | 15674 |
| 3 | tcp | 35.212.240.3 | 34533 | 165.56.53.149 | 15674 |
| 4 | dns | 10.65.179.189 | 12718 | 165.56.53.149 | 15674 |
| 5 | https | 10.65.145.37 | 34490 | 165.56.53.161 | 38013 |
| 6 | https | 10.65.14.63 | 43956 | 165.56.53.178 | 27552 |
| 7 | https | 10.66.32.44 | 37573 | 165.56.53.141 | 29821 |
| 8 | udp | 172.21.242.243 | 10188 | 41.72.123.88 | 55777
you should initialize natted_ip and natted_port outside of for like below code.
because this variables save data from previous record and you don't clear them. it can be happen for all variables that can be null.
natted_ip = null;
natted_port = null;
for(String string:splitIP_and_port){
natted_ip = splitIP_and_port[0].trim();
natted_port = splitIP_and_port[1].trim();
}

Iterating through lists of list in java

I have two tables User and Roles with one-to-one relation as below.
User
_________________________________________
| Id | user_name | full_name | creator |
_________________________________________
| 1 | a | A | a |
| 2 | b | B | a |
| 3 | c | C | a |
| 4 | d | D | c |
| 5 | e | E | c |
| 6 | f | F | e |
| 7 | g | G | e |
| 8 | h | H | e |
| 9 | i | I | e |
|10 | j | J | i |
_________________________________________
Roles
_______________________________________
| id | user_mgmt | others | user_id |
_______________________________________
| 1 | 1 | 1 | 1 |
| 2 | 0 | 1 | 2 |
| 3 | 1 | 0 | 3 |
| 4 | 0 | 1 | 4 |
| 5 | 1 | 1 | 5 |
| 6 | 0 | 1 | 6 |
| 7 | 0 | 0 | 7 |
| 8 | 0 | 0 | 8 |
| 9 | 1 | 0 | 9 |
________________________________________
The Roles table have boolean columns, so if an User have user_mgmt role he can add many users (How many users can be added by an user is not definite). I want to fetch all users created by an user and his child users ( a is parent, c is child of a and e is child of c ..) .
Here is my code to fetch users
public void loadUsers(){
List<Users> users = new ArrayList<>();
String creator = user.getUserName();
List<Users> createdUsers = userService.getUsersByCreator(creator);
for(Users user : createdUsers) {
Roles role = createdUsers.getRoles();
if(role.isEmpMgnt()){
users.add(user);
loadUsers();
}
}
}
This gives me an stack overflow error. If i don't call loadUsers() recursively it returns only a single child result. So is there any solutions to this ? Thanks for any help in advance.
This gives you stack overflow error because a has creator a. So you have infinite loop for user a. For a you should set creator to null or skip self references in code.
Also you should pass current user into loadUsers() method and read only users that are created by it. Like
public void loadUsers(String creator)
and only process users created by that creator. Here
String creator = user.getUserName();
what is user? You should use creator. Question is how do you obtain initial creator. Probably initial creator should be user where creator is null.

How does Hibernate know which member variable to populate when an object has two members of the same class

I've got a MySQL database schema with 3 tables as follows:
mysql> describe results;
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| run_at | datetime | YES | | NULL | |
| trials | int(10) unsigned | YES | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
mysql> describe result_details;
+------------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| results_id | int(10) | NO | | NULL | |
| summarys_id | int(10) | YES | | NULL | |
+------------------------+------------------+------+-----+---------+----------------+
mysql> describe summarys;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| mean | double | YES | | NULL | |
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
+-------+------------------+------+-----+---------+----------------+
Where a Result object can have several ResultDetail members. However, semantically, it makes sense to have one of these details stand out among the rest as a 'overall' detail. Therefore, I have the following classes:
Result.java (some members and methods removed for brevity)
#Entity
#Table(name="results")
public class Result extends BaseEntity {
#Column(name="run_at")
#Temporal(TemporalType.TIMESTAMP)
private Date runAt;
#Column(name="trials")
private Integer trials;
#OneToOne(mappedBy="result", cascade = {CascadeType.ALL})
private ResultDetails overallStats;
#OneToMany(mappedBy="result", cascade = {CascadeType.ALL})
private List<ResultDetails> resultDetails = new ArrayList<ResultDetails>();
}
ResultDetail.java
#Entity
#Table(name="result_details")
public class ResultDetails extends BaseEntity {
#ManyToOne
#JoinColumn(name = "results_id", nullable=false)
#NotNull
private Result result;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="summarys_id", nullable=true)
private Summary summary;
}
When I create persistent entities from my main as follows:
public static void main (String [] args) {
Result result = new Result();
ResultDetails detail1 = new ResultDetails();
ResultDetails detail2 = new ResultDetails();
Summary s1 = new Summary();
Summary s2 = new Summary();
result.setRunAt(new Date());
result.setTrials(1000000);
detail1.setResult(result);
s1.setMean(3.0);
detail1.setSummary(s1);
result.setOverallStats(detail1);
detail2.setCybervarResult(result);
s2.setMean(11.0);
detail2.setSummary(s2);
result.addDetails(detail2);
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.saveOrUpdate(result);
session.getTransaction().commit();
HibernateUtil.shutdown();
}
It adds the appropriate rows to the tables. However, when I retrieve the data as demonstrated by the following additional main file:
Session session = HibernateUtil.getSessionFactory().openSession();
Result result = session.get(CybervarResult.class, 6);
result.getOverallStats().getSummary();
result.getResultDetails().size();
HibernateUtil.shutdown();
System.out.println(result.getOverallStats().getSummary().getMean());
System.out.println(result.getResultDetails().get(0).getSummary().getMean());
Hibernate is able to correctly populate the 'overallStats' and 'resultDetails' objects. How is it able to differentiate the two rows in the result_details table? As far as I can tell, there is nothing to distinguish the two from each other. Does Hibernate implement hidden tables/rows to manage which member variables correspond to which rows? If I were to create this database from mysql queries instead of through the hibernate API, how would Hibernate know which row should be the 'overallStats' and which rows should belong to the 'resultDetails' collection?
For reference, the rows created look as follows:
mysql> select * from results;
+----+---------------------+---------+
| id | run_at | trials |
+----+---------------------+---------+
| 6 | 2017-11-13 09:27:52 | 1000000 |
+----+---------------------+---------+
mysql> select * from result_details;
+----+------------+-------------+
| id | results_id | summarys_id |
+----+------------+-------------+
| 10 | 6 | 14 |
| 11 | 6 | 15 |
+----+------------+-------------+
hibernate.cfg.xml
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/usersdb</property>
<property name="hibernate.connection.username">test</property>
<property name="hibernate.connection.password">test</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">validate</property>

Connection to the DataBase lost after X seconds of inactivity

I have this error after 20-30 minutes of inactivity
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 2.383.932 milliseconds ago.
The last packet sent successfully to the server was 21.351 milliseconds ago.
I have checked Data Base options,but they are ok
mysql> show session variables like '%timeout%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| table_lock_wait_timeout | 50 |
| wait_timeout | 28800 |
+----------------------------+-------+
10 rows in set (0.00 sec)
mysql> show global variables like '%timeoout%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| table_lock_wait_timeout | 50 |
| wait_timeout | 28800 |
+----------------------------+-------+
10 rows in set (0.00 sec)
Connection class:
public class ConnectionDB {
Connection con;
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://XXXXXXXXXX:3306/";
String nomeutente = "XXXXXXX";
String password = "XXXXXXXX";
String nomedatabase = "XXXXXX";
public Boolean ok = false;
public Connection connect(){
try {
Class.forName(driver);
con = DriverManager.getConnection(url+nomedatabase,nomeutente,password);
ok = true;
return con;
} catch (ClassNotFoundException | SQLException e) {
new ErrorLog();
e.printStackTrace();
ok = false;
return null;
}
}
}

How to join same table with JPQL

I have a table in my database, which contains sportsresults, and I need to select the last result for a competitor on a specific eventstage from a table.
I have this table:
+----------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+-------+
| EventStageID | int(11) | NO | PRI | NULL | |
| CompetitorID | int(11) | NO | PRI | NULL | |
| Lap | int(11) | NO | PRI | NULL | |
| Time | varchar(255) | YES | | NULL | |
| Status | varchar(255) | YES | | NULL | |
| PitstopCount | int(11) | YES | | NULL | |
| Grid | int(11) | YES | | NULL | |
| FastestLapTime | varchar(255) | YES | | NULL | |
| Substatus | varchar(255) | YES | | NULL | |
| Points | decimal(10,2) | YES | | NULL | |
| Position | int(11) | YES | | NULL | |
| StageType | int(11) | YES | | NULL | |
+----------------+---------------+------+-----+---------+-------+
I can select from the table with normal SQL query like this:
SELECT * FROM
(SELECT EventStageID as esi, CompetitorID as cid, Max(Lap) as MaxLap FROM srt_outright_season_event_stage_result_live WHERE EventStageID = 191666 GROUP BY CompetitorID) as y
LEFT JOIN
(SELECT * FROM srt_outright_season_event_stage_result_live) as x
ON x.CompetitorID = y.cid AND x.Lap = y.MaxLap AND x.EventStageID = y.esi;
Which gives the following result:
+--------+--------+--------+--------------+--------------+------+----------+--------+--------------+------+----------------+-----------+--------+----------+-----------+
| esi | cid | MaxLap | EventStageID | CompetitorID | Lap | Time | Status | PitstopCount | Grid | FastestLapTime | Substatus | Points | Position | StageType |
+--------+--------+--------+--------------+--------------+------+----------+--------+--------------+------+----------------+-----------+--------+----------+-----------+
| 191666 | 4521 | 0 | 191666 | 4521 | 0 | Finished | NULL | NULL | NULL | 2:00.175 | NULL | NULL | 4 | 5 |
| 191666 | 4524 | 0 | 191666 | 4524 | 0 | Finished | NULL | NULL | NULL | 2:04.053 | NULL | NULL | 10 | 5 |
| 191666 | 4533 | 0 | 191666 | 4533 | 0 | Finished | NULL | NULL | NULL | NULL | NULL | NULL | 13 | 5 |
| 191666 | 4538 | 0 | 191666 | 4538 | 0 | Finished | NULL | NULL | NULL | 2:01.218 | NULL | NULL | 6 | 5 |
| 191666 | 5769 | 0 | 191666 | 5769 | 0 | Finished | NULL | NULL | NULL | 2:00.050 | NULL | NULL | 3 | 5 |
| 191666 | 7135 | 0 | 191666 | 7135 | 0 | Finished | NULL | NULL | NULL | 1:59.431 | NULL | NULL | 1 | 5 |
| 191666 | 7138 | 0 | 191666 | 7138 | 0 | Finished | NULL | NULL | NULL | NULL | NULL | NULL | 18 | 5 |
| 191666 | 7610 | 0 | 191666 | 7610 | 0 | Finished | NULL | NULL | NULL | 1:59.486 | NULL | NULL | 2 | 5 |
+--------+--------+--------+--------------+--------------+------+----------+--------+--------------+------+----------------+-----------+--------+----------+-----------+
I have this Entity class:
#Entity(name = "event_stage_result_live")
public class EventStageResultLive {
#EmbeddedId
private PKEventStageResultLive pkEventStageResultLive;
// Composite PK contains EventStageID, CompetitorID and Lap
#Column(name = "Time")
private String time;
#Column(name = "Status")
private String status;
#Column(name = "PitstopCount")
private Integer pitstopCount;
#Column(name = "Grid")
private Integer grid;
#Column(name = "Position")
private Integer position;
#Column(name = "FastestLapTime")
private String fastestLapTime;
#Column(name = "Substatus")
private String substatus;
#Column(name = "Points")
private Float points;
#Column(name = "StageType")
private StageType stageType;
// getters and setters...
}
I think in SQL you can do something like this. I dont think join is required.
select * from srt_outright_season_event_stage_result_live c
where c.CompetitorID = :competitorID and c.EventStageID = 191666
and c.Lap = (select max(d.lap) from srt_outright_season_event_stage_result_live d
where d.CompetitorID = :competitorID and d.EventStageID = 191666 )
Passed to JPQL is
select e from EventStageResultLive e
where e.pkEventStageResultLive.CompetitorID = :competitorID and c.pkEventStageResultLive.EventStageID = 191666
and e.pkEventStageResultLive.Lap = (select max(d.pkEventStageResultLive.lap) from EventStageResultLive d
where d.pkEventStageResultLive.CompetitorID = :competitorID and d.pkEventStageResultLive.EventStageID = 191666 )
Assuming
public class PKEventStageResultLive{
private int CompetitorID ;
private int EventStageID ;
private int Lap;
}
If the name of the properties are different correct the name in the JPQL
And competitorID as a named parameter.

Categories