I want to create a custom Spring Data query which will find all training for a trainer between two dates.
Training class looks like:
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
@Builder
public class Training extends AbstractBaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "training", cascade = CascadeType.ALL)
List<Exercise> exercises = new ArrayList<>();
@Column(name = "difficulty_level", nullable = false)
@Enumerated(EnumType.STRING)
private DifficultyLevel difficultyLevel;
@Column(name = "completed")
boolean completed;
@OneToOne(targetEntity = Training.class, fetch = FetchType.LAZY)
private TrainingParticipants trainingParticipants;
@OneToOne(targetEntity = Training.class, fetch = FetchType.LAZY)
private TrainingDate trainingDate;
}
with nested classes like:
@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TrainingParticipants {
@Id
@GeneratedValue
private Long id;
@OneToOne(targetEntity = TrainingParticipants.class)
private User trainer;
@ElementCollection(targetClass = TrainingParticipants.class)
private Set<User> trainee;
}
and
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
class TrainingDate {
@Id
@GeneratedValue
private Long id;
private LocalDateTime startDate;
private LocalDateTime endDate;
}
AbstractBaseEntity for HashCodeEquals contract and @Version usage looks like:
@ToString
@MappedSuperclass
@Getter
@SuperBuilder
public abstract class AbstractBaseEntity {
@Version
protected long version = 0;
@JsonIgnore
@Transient
protected UUID uuid = UUID.randomUUID();
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AbstractBaseEntity that = (AbstractBaseEntity) o;
return uuid.equals(that.getUuid());
}
@Override
public int hashCode() {
return uuid.hashCode();
}
public AbstractBaseEntity(long version) {
this.version = version;
}
public AbstractBaseEntity() {
}
}
I created a Training repository with JpaRepository usage with method like:
@Repository
interface TrainingRepository extends JpaRepository<Training, Long> {
List<Training> findAllByTrainingParticipants_Trainer_IdAndTrainingStartDateLessThanEqualAndTrainingEndDateGreaterThanEqual(
Long trainerId,
LocalDateTime trainingStartDate,
LocalDateTime trainingEndDate);
default List<Training> findAllTrainerTrainingsBetweenStartAndEndDate(
Long trainerId,
LocalDateTime trainingStartDate,
LocalDateTime trainingEndDate) {
return findAllByTrainingParticipants_Trainer_IdAndTrainingStartDateLessThanEqualAndTrainingEndDateGreaterThanEqual(
trainerId, trainingStartDate, trainingEndDate);
}
}
With IntelliJ hints, I created a custom query which will find out all training of trainer between two dates. Problem is that with the above approach I am receiving and an exception which looks like below:
Caused by: java.lang.IllegalArgumentException: Failed to create the query for method public abstract java.util.List com.application.training.TrainingRepository.findAllByTrainingParticipants_Trainer_IdAndTrainingStartDateLessThanEqualAndTrainingEndDateGreaterThanEqual(java.lang.Long,java.time.LocalDateTime,java.time.LocalDateTime)! Unable to locate Attribute with the the given name [trainer] on this ManagedType [com.application.common.AbstractBaseEntity]
I am a little bit confused because in the past when I was cooperating with IDE hints that were working properly. At the same time, I understand that I can use the classic SQL approach but in this scenario Spring Data is desirable. I will be grateful for a suggestions on how to fix a query and reach a goal.
EDIT:
for variant without _ separator I have an error like:
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.appplication.training.TrainingRepository.findAllByTrainingParticipantsTrainerIdAndTrainingStartDateLessThanEqualAndTrainingEndDateGreaterThanEqual(java.lang.Long,java.time.LocalDateTime,java.time.LocalDateTime)! Unable to locate Attribute with the the given name [trainer] on this ManagedType [com.application.common.AbstractBaseEntity]
with separators it's looks like:
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.application.training.TrainingRepository.findAllByTrainingParticipants_Trainer_IdAndTrainingStartDateLessThanEqualAndTrainingEndDateGreaterThanEqual(java.lang.Long,java.time.LocalDateTime,java.time.LocalDateTime)! Unable to locate Attribute with the the given name [trainer] on this ManagedType [com.application.common.AbstractBaseEntity]
EDIT 2: After suggestion @Simon Martinelli there is an error like:
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.application.training.TrainingRepository.findAllByTrainingParticipants_Trainer_IdAndTrainingStartDateLessThanEqualAndTrainingEndDateGreaterThanEqual(java.lang.Long,java.time.LocalDateTime,java.time.LocalDateTime)!