jpaspring-data-jpajpa-2.0jpa-2.1

How to use JpaRepository method in the Jpa Entity Lifecycle callbacks?


How to create new Transaction in the @PostUpdate JPA Entity Lifecycle methods? I am not able to @Autowire the AuthorRepository method there and it's always coming null.

package com.bookstore.entity;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Author implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String genre;
    private int age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGenre() {
        return genre;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
    this.age = age;
}

@Override
public String toString() {
    return "Author{" + "id=" + id + ", name=" + name
            + ", genre=" + genre + ", age=" + age + '}';
}

}

AuthorRepository.java

@Repository
public interface AuthorRepository extends JpaRepository<Author, Long> {
    
    @Transactional(readOnly=true)
    Author findByName(String name);   
}

AuthorListener:

@Component
public class BookListener {
    
    @Autowired
    private  AuthorRepository authorRepository;
    

    @PrePersist
    void onPrePersist(Book book) {
        System.out.println("BookListener.onPrePersist(): " + book);
    }

    @PostPersist
    void onPostPersist(Book book) {
        System.out.println("BookListener.onPostPersist(): " + book);
    }

    @PostLoad
    void onPostLoad(Book book) {
        System.out.println("BookListener.onPostLoad(): " + book);
    }

    @PreUpdate
    void onPreUpdate(Book book) {
        System.out.println("BookListener.onPreUpdate(): " + book);
    }

    @PostUpdate
    void onPostUpdate(Book book) {
        System.out.println("BookListener.onPostUpdate(): " + book);
       // authorRepository.findAll()
    }

    @PreRemove
    void onPreRemove(Book book) {
        System.out.println("BookListener.onPreRemove(): " + book);
        System.out.println(authorRepository.count());
    }

    @PostRemove
    void onPostRemove(Book book) {
        System.out.println("BookListener.onPostRemove(): " + book);
    }
}

BookService.java

import com.bookstore.repository.AuthorRepository;
import com.bookstore.entity.Author;
import com.bookstore.entity.Paperback;
import com.bookstore.entity.Ebook;
import com.bookstore.repository.EbookRepository;

import java.util.Optional;

import org.springframework.stereotype.Service;
import com.bookstore.repository.PaperbackRepository;
import org.springframework.transaction.annotation.Transactional;

@Service
public class BookstoreService {

    private final AuthorRepository authorRepository;
    private final PaperbackRepository paperbackRepository;
    private final EbookRepository ebookRepository;

    public BookstoreService(AuthorRepository authorRepository,
            PaperbackRepository paperbackRepository,
            EbookRepository ebookRepository) {

        this.authorRepository = authorRepository;
        this.paperbackRepository = paperbackRepository;
        this.ebookRepository = ebookRepository;
    }

    @Transactional
    public void persistAuthorWithBooks() {

        Author author = new Author();
        author.setName("Alicia Tom");
        author.setAge(38);
        author.setGenre("Anthology");

        Paperback paperback = new Paperback();
        paperback.setIsbn("002-AT");
        paperback.setTitle("The beatles anthology");
        paperback.setSizeIn("7.5 x 1.3 x 9.2");
        paperback.setWeightLbs("2.7");
        paperback.setAuthor(author);

        Ebook ebook = new Ebook();
        ebook.setIsbn("003-AT");
        ebook.setTitle("Anthology myths");
        ebook.setFormat("kindle");
        ebook.setAuthor(author);

        authorRepository.save(author);
        paperbackRepository.save(paperback);
        ebookRepository.save(ebook);
    }
    
    @Transactional
    public void update() {
        Optional<Author> optional = authorRepository.findById(1L);
        if(optional.isPresent()) {
            Author author = optional.get();
            author.setName("Johnn Doe");
            authorRepository.save(author);
        }
    }

    @Transactional
    public void fetchAndRemovePaperback() {
        Paperback paperback = paperbackRepository
                .findByTitle("The beatles anthology");        
        paperbackRepository.delete(paperback);
    }

    @Transactional
    public void fetchAndRemoveEbook() {        
        Ebook ebook = ebookRepository
                .findByTitle("Anthology myths");         
        ebookRepository.delete(ebook);
    }  
}

Solution

  • Some of the solutions already provided in the below answer Injecting a Spring dependency into a JPA EntityListener

    Try it like in BookListener class.

    @Autowired
    private ObjectFactory<AuthorRepository> authorRepository;
    

    and use it like

    authorRepository.getObject().findById(1L)