skip to Main Content

When I try to delete a review nothing is deleted and nothing is thrown.
I already tried changing some of the cascade types but at the moment I can’t figure out what the problem is. At first I was using the delete method provided by ‘CrudRepository’, where you have to pass the object reference instead of deleting by Id but, didn’t work also.

Entities

@Entity(name = "product_postgresql")
@Getter
public class Product {

    @Id
    @Column(nullable = false, unique = true)
    private String sku;

    @Column(nullable = false)
    private String designation;

    @Column(nullable = false)
    private String description;

    @Column(nullable = false)
    private double aggregatedRating;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "product", fetch = FetchType.LAZY)
    private List<Review> reviews;

    protected Product() {
    }

    public Product(final String sku, final String designation, final String description, final double aggregatedRating) {
        this.sku = sku;
        this.designation = designation;
        this.description = description;
        this.aggregatedRating = aggregatedRating;
    }
}

@Getter
@Entity(name = "review_postgresql")
public class Review {

    @Id
    private String id;

    @Version
    private long version;

    @Column(nullable = false)
    private String approvalStatus;

    @Column(nullable = false)
    private String text;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "review", fetch = FetchType.EAGER)
    @Setter
    private List<Vote> votes;

    private String report;

    @Column(nullable = false)
    private LocalDate publishingDate;

    @Column(nullable = false)
    private String funFact;

    @Column(nullable = false)
    private double rating;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
    @JoinColumn(name = "product_sku", nullable = false)
    private Product product;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    protected Review() {
    }

    public Review(final String id, final long version, final String approvalStatus, final String text,
                  final String report, final LocalDate publishingDate, final String funFact, final Double rating,
                  final Product product, final User user) {

        this.id = id;
        this.version = version;
        this.approvalStatus = approvalStatus;
        this.text = text;
        this.report = report;
        this.publishingDate = publishingDate;
        this.funFact = funFact;
        this.rating = rating;
        this.product = product;
        this.user = user;
    }
}
@Entity(name = "user_postgresql")
@Getter
public class User {

    @Id
    private String id;

    @Email
    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String fullName;

    @Column(nullable = false)
    private String role; //why multiple roles?

    @Column(nullable = false, unique = true)
    private String nif;

    @Column(nullable = false)
    private String address;

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Review> reviews;

    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Vote> votes;

    protected User() {
    }

    public User(final String id, final String email, final String password, final String fullName,
                final String role, final String nif, final String address) {
        this.id = id;
        this.email = email;
        this.password = password;
        this.fullName = fullName;
        this.role = role;
        this.nif = nif;
        this.address = address;
    }
}
@Entity(name = "vote_postgresql")
@Getter
public class Vote implements Serializable {

    @EmbeddedId
    private VoteKey id;

    @Column(nullable = false)
    private String vote;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("user_id")
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("review_id")
    @JoinColumn(name = "review_id", nullable = false)
    private Review review;

    protected Vote() {
    }

    public Vote(User user, Review review, String vote) {
        this.id = new VoteKey(user.getId(), review.getId());
        this.user = user;
        this.review = review;
        this.vote = vote;
    }
}

JPA Repository

@ConditionalOnProperty(value = "spring.repositories.targetPackage", havingValue = "mongodb")
public interface ReviewRepositoryMongodb extends CrudRepository<Review, String> {

    @Modifying
    @Query("DELETE FROM review_postgresql r WHERE r.id = :id")
    void deleteById(String id);
}

2

Answers


    1. The problem might be caused by the bidirectional relationships between the entities, which require synchronization of both sides when performing operations.
    2. To delete a Review entity, you need to remove it from the Product and User entities that reference it, otherwise the foreign key constraints will prevent the deletion.
    3. You can use orphanRemoval = true in the @OneToMany annotations of Product and User entities to automatically delete the Review entity when it is removed from the collections.
    4. Alternatively, you can use entityManager.remove (review) instead of tokenRepository.delete (review), which will cascade the removal operation to the associated entities.
    Login or Signup to reply.
    1. Ensure that you have the ReviewRepositoryMongodb configured correctly in your application and that it’s being used in the appropriate part of your code.
    2. Add a custom method to the `ReviewRepositoryMongodb that deletes a review by its ID. It seems you already have this method, but I’ll provide it here for reference:
    @Modifying
    @Query("DELETE FROM review_postgresql r WHERE r.id = :id")
    void deleteById(String id) {
        try {
            entityManager.createQuery("DELETE FROM review_postgresql r WHERE r.id = :id")
                    .setParameter("id", id)
                    .executeUpdate();
        } catch (Exception e) {
            // Log the exception
            logger.error("Error deleting review with ID: " + id, e);
            throw e; // Rethrow the exception to handle it in your service layer, if needed.
        }
    }
    
    
    1. Ensure that your application is correctly invoking the custom delete method using the repository. For example:
    @Autowired
    private ReviewRepositoryMongodb reviewRepository;
    
    // Somewhere in your service or controller, use this method to delete a review.
    public void deleteReviewById(String reviewId) {
        reviewRepository.deleteById(reviewId);
    }
    
    1. Verify that you’re providing the correct id when calling the deleteReviewById method. Ensure that the id corresponds to an existing review in your database.
    2. Make sure the calling code is wrapped in a transaction. If it’s not already, consider adding the @Transactional annotation to your service or controller method to ensure proper transaction management.
    3. Add logging and exception handling to your delete operation,to assist in debugging and understanding any issues that might occur during the deletion process.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search