Monoxyd
Monoxyd

Reputation: 486

Delete entity after specified time with JpaRepository

I am using Spring Boot and H2 db. I have a Product entity and I want my application to be able to remove the product from the database, but my requirement is this: first set the active flag to false ( then this row will not be taken into account during fetching ) and after a specific period of time completely remove this row from db.

@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(generator = "inc")
    @GenericGenerator(name = "inc", strategy = "increment")
    private int id;
    private boolean active = true;
    // getters & setters
}

And my method from the service layer responsible for setting the active flag to false and later complete deletion (I have nothing that does the second part of my requirement - complete deletion after specific period of time)

@Transactional
public void deleteProduct(int id) {
    var target = repository.findProductById(id)
            .orElseThrow(() -> new IllegalArgumentException("No product with given id"));
    target.setActive(false);
    // what should I add here to remove the target after a specific time?
}

EDIT

OK, I solved my problem:

@Transactional
public void deleteProduct(int id) {
    var target = repository.findProductByIdAndActiveTrue(id)
            .orElseThrow(() -> new IllegalArgumentException("No product with gicen id"));
    target.setActive(false);
    // complete removal after 150 seconds
    new Thread(() -> {
        try {
            Thread.sleep(150000);
            repository.deleteById(id);
        } catch (Exception e) {
            logger.error("Error removing the product");
        }
    }).start();
}

But now my question is if this is a safe solution as the user may start too many threads now so I think there is a better solution to my problem (safer in terms of multithreading)

Upvotes: 1

Views: 1242

Answers (1)

fludas
fludas

Reputation: 58

I am not an expert but i think what you trying to achieve is bad practice.

I believe you should do a scheduling, for example ones per day. You should update in db the value active. Set a schedule that will check the entries each time and if they have an active value of false then delete. Something like this:

public void deleteProduct(int id) {
    
    //update value to false
    repository.updateProductValue(id,false);
}

and your scheduling method:

@Scheduled(fixedRate = 150000)
public void deleteNonActiveProducts() {

        List<Product> products = repository.findAllByFalseValue();
        products.forEach(product -> repository.deleteById(product.getId());
}

With this what you are doing is that every 150000 milliseconds you repeat that task and each execution of this task is independent and non parallel.

Hope is useful to you.

Upvotes: 2

Related Questions