在升级到Hibernate6和Spring Boot3之后,下面的代码抛出了一个错误(Cannot project java.lang.Short to com.cubetrek.cubetrekplayground.database.TrackData$Sharing; Target type is not an interface and no matching Converter found
).
@Entity类如下所示:
@Entity(name = "trackdata")
@Table(name = "trackdata")
public class TrackData implements Serializable {
public enum Sharing {
PRIVATE, FRIENDS, PUBLIC;
}
@Getter
@Setter
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Getter
@Setter
@Column(name = "title")
private String title;
@Getter
@Setter
@Enumerated(EnumType.ORDINAL)
@Column(name = "sharing")
private Sharing sharing;
// loads of other fields and getters and setters...
//and here's the interface
public interface TrackMetadata {
Long getId();
@JsonSerialize(using = TitleSerializer.class, as=String.class)
String getTitle();
@Enumerated(EnumType.ORDINAL)
Sharing getSharing();
}
}
在TrackDataRepository中:
public interface TrackDataRepository extends JpaRepository<TrackData, Long>, JpaSpecificationExecutor<TrackData> {
Optional<TrackData> findById(Long id);
// and here's the query in question:
@Query(value = "SELECT trackdata.id, trackdata.title, trackdata.sharing FROM trackdata " +
"WHERE trackdata.id = :trackid", nativeQuery = true)
TrackData.TrackMetadata getMetadata(long trackid);
}
实体的工作方式与预期一致:
TrackData trackData = trackDataRepository.getReferenceById(21682L);
System.out.println(trackData.getSharing()); //works fine
但界面却搞砸了:
TrackData.TrackMetadata td2 = trackDataRepository.getMetadata(21682L);
System.out.println(td2.getTitle()); //works
System.out.println(td2.getSharing()); //ERROR!!
错误似乎是因为从short到enum的投影:
100
此外,定制的Converter似乎不能完成此任务:
@Converter
public static class SharingConverter implements AttributeConverter<Sharing, Short> {
@Override
public Short convertToDatabaseColumn(Sharing sharing) {
return (short)sharing.ordinal();
}
@Override
public Sharing convertToEntityAttribute(Short dbData) {
return Sharing.values()[dbData];
}
}
public interface TrackMetadata {
Long getId();
@JsonSerialize(using = TitleSerializer.class, as=String.class)
String getTitle();
@Convert(converter = SharingConverter.class)
Sharing getSharing();
}