There is a class with an EmbeddedId.
@Entity
@Getter
@Setter
@Table(name = "indicator_values")
public class IndicatorValue {
@EmbeddedId
public IndicatorValueId id;
@Column(name = "value")
public BigDecimal value;
public IndicatorValue() {}
public IndicatorValue(
IndicatorValueId id,
BigDecimal value
) {
this.id = id;
this.value = value;
}
// Constructor used for experimentation (invoked in the repository)
public IndicatorValue(
String categoryCode,
String indicatorCode,
BigDecimal value,
LocalDate effectiveDate
) {
this.value = value;
this.id = new IndicatorValueId(categoryCode, indicatorCode, effectiveDate);
}
}
Alongside it, there is an @Embeddable class that defines this ID.
@Embeddable
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@Getter
@Setter
public class IndicatorValueId implements Serializable {
@Column(name = "category_code")
private String categoryCode;
@Column(name = "indicator_code")
private String indicatorCode;
@Column(name = "effective_date")
private LocalDate effectiveDate;
}
And there is a repository (I’ve tried different methods to verify the result—this is not the complete list).
public interface IndicatorValueRepository extends JpaRepository<IndicatorValue, IndicatorValueId> {
@Query("""
SELECT iv
FROM IndicatorValue iv
WHERE iv.id.indicatorCode = :indicatorCode
AND iv.id.effectiveDate < :effectiveDate
ORDER BY iv.id.effectiveDate DESC
""")
List<IndicatorValue> findByIndicatorCodeBeforeDate(
@Param("indicatorCode") String indicatorCode,
@Param("effectiveDate") LocalDate effectiveDate
);
@Query("""
SELECT NEW by.vezhlivec.normsservice.entity.IndicatorValue(
iv.id.categoryCode,
iv.id.indicatorCode,
iv.value,
iv.id.effectiveDate
)
FROM IndicatorValue iv
WHERE iv.id.indicatorCode = :indicatorCode
AND iv.id.categoryCode IS NULL
AND iv.id.effectiveDate < :effectiveDate
ORDER BY iv.id.effectiveDate DESC
""")
List<IndicatorValue> findByIndicatorCodeBeforeDate1(
@Param("indicatorCode") String indicatorCode,
@Param("effectiveDate") LocalDate effectiveDate
);
List<IndicatorValue> findByIdIndicatorCode(String indicatorCode);
List<IndicatorValue> findByValue(BigDecimal value);
}
The core issue is that data is retrieved correctly only when I select a specific field, use a native query, or perform mapping via a constructor (as in findByIndicatorCodeBeforeDate1).
In all other cases—when attempting to fetch the entity or a list of entities—I either get null or a List with the correct number of elements, but every element is null.
Even the standard findById() returns null, despite the record definitely existing in the database.
Here is a test snippet from the service
List<IndicatorValue> iv = indicatorValueRepository.findByIdIndicatorCode("worker_4th_grade_hour_rate_construction");
System.out.println(iv);
List<IndicatorValue> v = indicatorValueRepository.findByValue(new BigDecimal("13.02"));
System.out.println(v);
List<IndicatorValue> iv1 = indicatorValueRepository
.findByIndicatorCodeBeforeDate("worker_4th_grade_hour_rate_construction", period.atDay(1));
System.out.println(iv1);
List<IndicatorValue> iv2 = indicatorValueRepository
.findByIndicatorCodeBeforeDate1("worker_4th_grade_hour_rate_construction", period.atDay(1));
for (IndicatorValue iv3 : iv2) {
log.debug("Код категории: {}, код индикатора: {}, значение: {}, дата: {}",
iv3.getId().getCategoryCode(),
iv3.getId().getIndicatorCode(),
iv3.getValue(),
iv3.getId().getEffectiveDate());
}
Optional<IndicatorValue> iv4 = indicatorValueRepository
.findById(new IndicatorValueId(
null,
"worker_4th_grade_hour_rate_construction",
LocalDate.of(2025, 9, 1)
)
);
System.out.println(iv4.orElse(null));
and the corresponding log output.
2025-11-28T22:28:44.318+03:00 DEBUG 414781 --- [nio-8080-exec-2] org.hibernate.SQL :
select
iv1_0.category_code,
iv1_0.effective_date,
iv1_0.indicator_code,
iv1_0.value
from
indicator_values iv1_0
where
iv1_0.indicator_code=?
2025-11-28T22:28:44.323+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.324+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.324+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
[null, null, null]
2025-11-28T22:28:44.326+03:00 DEBUG 414781 --- [nio-8080-exec-2] org.hibernate.SQL :
select
iv1_0.category_code,
iv1_0.effective_date,
iv1_0.indicator_code,
iv1_0.value
from
indicator_values iv1_0
where
iv1_0.value=?
2025-11-28T22:28:44.327+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.327+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.327+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.327+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.327+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
[null, null, null, null, null]
2025-11-28T22:28:44.330+03:00 DEBUG 414781 --- [nio-8080-exec-2] org.hibernate.SQL :
select
iv1_0.category_code,
iv1_0.effective_date,
iv1_0.indicator_code,
iv1_0.value
from
indicator_values iv1_0
where
iv1_0.indicator_code=?
and iv1_0.effective_date<?
order by
iv1_0.effective_date desc
2025-11-28T22:28:44.331+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
[null]
2025-11-28T22:28:44.333+03:00 DEBUG 414781 --- [nio-8080-exec-2] org.hibernate.SQL :
select
iv1_0.category_code,
iv1_0.indicator_code,
iv1_0.value,
iv1_0.effective_date
from
indicator_values iv1_0
where
iv1_0.indicator_code=?
and iv1_0.category_code is null
and iv1_0.effective_date<?
order by
iv1_0.effective_date desc
2025-11-28T22:28:44.334+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (1:VARCHAR) -> [null]
2025-11-28T22:28:44.334+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (2:VARCHAR) -> [worker_4th_grade_hour_rate_construction]
2025-11-28T22:28:44.334+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (3:NUMERIC) -> [13.02]
2025-11-28T22:28:44.334+03:00 TRACE 414781 --- [nio-8080-exec-2] org.hibernate.orm.jdbc.extract : extracted value (4:DATE) -> [2024-09-01]
2025-11-28T22:28:44.335+03:00 DEBUG 414781 --- [nio-8080-exec-2] b.v.n.s.i.u.IndicatorsUpdateService : Код категории: null, код индикатора: worker_4th_grade_hour_rate_construction, значение: 13.02, дата: 2024-09-01
2025-11-28T22:28:44.350+03:00 DEBUG 414781 --- [nio-8080-exec-2] org.hibernate.SQL :
select
iv1_0.category_code,
iv1_0.effective_date,
iv1_0.indicator_code,
iv1_0.value
from
indicator_values iv1_0
where
(
iv1_0.category_code, iv1_0.effective_date, iv1_0.indicator_code
) in ((?, ?, ?))
null
IndicatorValueshould also exhibit a constructor that accepts an instance ofIndicatorValueId. So,public IndicatorValue(IndicatorValueId id, BigDecimal value).@AllArgsConstructoronly inIndicatorValueIdnot inIndicatorValue.@AllArgsConstructorand@NoArgsConstructor. Later, I replaced them with explicitly written constructors. When drafting the post, I simply omitted listing all of them (including@AllArgsConstructor) because, as far as I understand,@AllArgsConstructorisn’t strictly required in this context. But please believe me—it is present. I’ve even tried making the fieldspublicto rule out visibility issues, and that didn’t help either.IndicatorValuewithIndicatorValueId's fields rather than an actual instance, I thought that could be the cause :/ I'll keep scratching my head though. Maybe somebody else might be able to help you with the updated version of your code.