Search code examples
spring-bootspring-data-jpaannotations

spring boot jpa is updating my database when I am using find by query


Here is the code for all 3 entities. Whenever I make repo.findByUserJavaIDAndCohortIdAndStatusInOrderByLastUpdatedDesc() This updates the last_updated column in my database as well.

public abstract class BaseEntity     {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(unique = true)
        protected Long id;
    
        @Column(unique = true, updatable = false, nullable = false)
        protected UUID uuid;
    
        @Builder.Default
        @Column(name = "is_deleted", nullable = false, columnDefinition = "bool default false")
        @JsonIgnore
        protected Boolean isDeleted=false;
    
        @Column(name = "created", nullable = false, updatable = false)
        @CreationTimestamp
        @JsonIgnore
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
        protected Date created;
    
        @Column(name = "last_updated", nullable = false)
        @UpdateTimestamp
        @JsonIgnore
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
        protected Date lastUpdated;
    
        public BaseEntity() {
            this.uuid = UUID.randomUUID();
            this.isDeleted = false;
        }
    }
    
    
    @Table(name = "task")
    public class Task extends BaseEntity {
    
        @NotNull
        @Column(nullable = false)
        private String title;
    
        @NotNull
        @Column(nullable = false)
        @Enumerated(EnumType.STRING)
        private Source source;
    
        @NotNull
        @Column(name="remote_id", nullable = false)
        @JsonIgnore
        private String remoteId;
    
        @NotNull
        @Column(name = "cohort_id", nullable = false)
        private Long cohortId;
    
        @Builder.Default
        @Column(nullable = false)
        @Enumerated(EnumType.STRING)
        @NotNull
        private TaskState state = TaskState.UPCOMING;
    
        @Column(nullable = false)
        @Enumerated(EnumType.STRING)
        @NotNull
        private EventType type;
    
        @NotNull
        @Length(max = 5000)
        @Column(nullable = false, columnDefinition ="LONGTEXT" )
        private String agenda;
    
        @Type(type = "TaskExtraDataType")
        @Column(name = "extra_data", columnDefinition = "jsonb")
        private TaskExtraData extraData;
    
        @Column(name = "schedule_time")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
        protected Date scheduleTime;
    
        @Column(name = "start_time")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
        protected Date startTime;
    
        @Column(name = "end_time")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
        protected Date endTime;
    
    }
    
    
    @Table(name = "user_task",
    public class UserTask extends BaseEntity {
    
        @ManyToOne
        @JoinColumn(name = "task_id")
        Task task;
    
        @NotNull
        @Column(name = "user_java_id", nullable = false)
        Long userJavaID;
    
        @NotNull
        @Column(name = "cohort_id", nullable = false)
        private Long cohortId;
    
        @Builder.Default
        @Column(nullable = false)
        @Enumerated(EnumType.STRING)
        UserTaskStatus status = UserTaskStatus.PENDING;
    
        @Type(type = "UserTaskExtraDataType")
        @Column(name = "extra_data", columnDefinition = "jsonb")
        private UserTaskExtraData userTaskExtraData;
    }

    public interface UserTaskRepository extends JpaRepository<UserTask, Long> {
        List<UserTask> findByUserJavaIDAndCohortIdAndStatusInOrderByLastUpdatedDesc(long userJavaId, long cohortId, List<UserTaskStatus> status);
    
    }

Solution

  • Hibernate calls equals method to check whether the object has been changed or not and before that it calls deep copy method to get a copy of the custom object. So I added equals to the method in my extra class and it worked perfectly.

    public class UserTaskExtraData implements Serializable {
        private Integer timeSpentInMins;
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            UserTaskExtraData that = (UserTaskExtraData) o;
            return Objects.equals(timeSpentInMins, that.timeSpentInMins);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(timeSpentInMins);
        }
    }
    public class TaskExtraData implements Serializable {
        private String link;
        private String expertName;
        private Long expertId;
        private String expertImageUrl;
        private String eventImageUrl;
        private double duration;
        private String expertEmail;
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            TaskExtraData that = (TaskExtraData) o;
            return Double.compare(that.duration, duration) == 0 && Objects.equals(link, that.link) && Objects.equals(expertName, that.expertName) && Objects.equals(expertId, that.expertId) && Objects.equals(expertImageUrl, that.expertImageUrl) && Objects.equals(eventImageUrl, that.eventImageUrl) && Objects.equals(expertEmail, that.expertEmail);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(link, expertName, expertId, expertImageUrl, eventImageUrl, duration, expertEmail);
        }
    }