I have created a sample project that uses H2
. You must change limit
and offset
part in which database you are using. For the delete operation, there is delete from table where id in (select id from table where .. order by .. limit .. offset ..)
is defined.
Note: Lombok
is used for getter
, setter
and toString
. It is not required.
DataRepository.java
public interface DataRepository extends JpaRepository<Data, Integer> {
@Query(value = "SELECT * FROM Data data WHERE data.jobName = :jobName ORDER BY data.dateTime limit :selectedSamples offset :firstIndex"
, nativeQuery = true)
List<Data>findByJobNameOrderByDateTimeLimit(@Param("jobName") String jobName, @Param("firstIndex") Integer firstIndex, @Param("selectedSamples") Integer selectedSamples);
@Transactional
@Modifying
@Query(value = "DELETE FROM Data data WHERE data.id in (select id from Data d where d.jobName = :jobName order by d.dateTime limit :selectedSamples offset :firstIndex)"
, nativeQuery = true)
void deleteByJobNameOrderByDateTime(@Param("jobName") String jobName, @Param("firstIndex") Integer firstIndex, @Param("selectedSamples") Integer selectedSamples);
}
Data.java
@lombok.Data
@Entity
@Table
public class Data {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "jobName")
private String jobName;
@Column(name = "dateTime")
private LocalDateTime dateTime;
public Data() {
}
public Data(String jobName, LocalDateTime dateTime) {
this.jobName = jobName;
this.dateTime = dateTime;
}
}
Test
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import java.util.List;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private DataRepository dataRepository;
@Test
void test1() {
// insert dummy records
dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(1)));
dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(2)));
dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(3)));
dataRepository.save(new Data("job1", LocalDateTime.now().minusMinutes(4)));
// get records
List<Data> dataList = dataRepository.findByJobNameOrderByDateTimeLimit("job1", 0, 4);
for (Data data : dataList) {
System.out.println(data);
}
// delete
dataRepository.deleteByJobNameOrderByDateTime("job1", 1, 2);
// get records
dataList = dataRepository.findByJobNameOrderByDateTimeLimit("job1", 0, 4);
for (Data data : dataList) {
System.out.println(data);
}
}
}
Output
Hibernate: SELECT * FROM Data data WHERE data.jobName = ? ORDER BY data.dateTime limit ? offset ?
Data(id=4, jobName=job1, dateTime=2021-01-08T05:25:31.830)
Data(id=3, jobName=job1, dateTime=2021-01-08T05:26:31.829)
Data(id=2, jobName=job1, dateTime=2021-01-08T05:27:31.827)
Data(id=1, jobName=job1, dateTime=2021-01-08T05:28:31.756)
Hibernate: DELETE FROM Data data WHERE data.id in (select id from Data d where d.jobName = ? order by d.dateTime limit ? offset ?)
Hibernate: SELECT * FROM Data data WHERE data.jobName = ? ORDER BY data.dateTime limit ? offset ?
Data(id=4, jobName=job1, dateTime=2021-01-08T05:25:31.830)
Data(id=1, jobName=job1, dateTime=2021-01-08T05:28:31.756)
Mysql
For mysql
delete operation is successful with below script.
Reference: MySQL DELETE FROM with subquery as condition - Answer
@Transactional
@Modifying
@Query(value = "DELETE FROM Data WHERE id in (select id from (select id from Data where jobName = :jobName order by dateTime limit :selectedSamples offset :firstIndex) x)"
, nativeQuery = true)
void deleteByJobNameOrderByDateTime(@Param("jobName") String jobName, @Param("firstIndex") Integer firstIndex, @Param("selectedSamples") Integer selectedSamples);