我根据NodeEntity的Enum属性查询问题。
定义了相关的NodeEntity:
@NodeEntity(label = "Entity")
public class MyEntity {
@GraphId
private Long internalId;
....
private State state;
@Transient
public enum State {
STATEONE, STATETWO, STATETHREE
}
....
它保存没有问题,状态Enum表示完美,我可以使用其他属性(字符串)查询完全没有问题。但问题是存储库中的以下查询:
@Query("MATCH (entity:Entity {state:{0}})" +
"RETURN entity")
List<MyEntity> findByState(MyEntity.State state)
即。找到具有给定状态的所有实体。
没有例外,但是使用它只会返回0个实体的列表。
我已尝试过各种各样的变体,例如使用WHERE子句,没有运气。
实体持久存在,在同一测试中使用findAll()返回预期的实体列表,其状态与我期望的完全相同。
有什么想法吗?
答案 0 :(得分:5)
不太确定值@Transient
添加到枚举的内容。无论如何,它不能作为Neo4j中的节点或关系持久化。将字段定义为应该与
private State state;
并从枚举中取消@Transient
注释。
有了它,SDN会忽略发送到派生查询的字段。
但是,如果你有充分的理由标记枚举@Transient,请分享它,我们将重新访问此案例。
答案 1 :(得分:0)
使用spring数据剩余接口在枚举字段中进行搜索存在一个普遍问题。仅在要查找值是否在值集合中的情况下,仅使用枚举到字符串转换器无法进行搜索:
public interface AppointmentRepository extends Neo4jRepository<Appointment, Long> {
Page<Appointment> findByDayOfWeekIn(@Param("days") List<DayOfWeek> days, Pageable pageable);
}
以上内容无法立即使用,因为neo4j会尝试将列表转换为您的媒体资源类型:DayOfWeek
为了解决此问题,我需要一个自定义转换器,该转换器可以处理提供值集合(搜索)和单个值(正常读写实体)的请求:
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class SearchQueryEnumConverter<T extends Enum> {
private Class<T> enumType;
public SearchQueryEnumConverter() {
enumType = (Class<T>) ((ParameterizedType) this.getClass()).getActualTypeArguments();
}
public Object toGraphProperty(Object value) {
if (Collection.class.isAssignableFrom(value.getClass())) {
List<T> values = (List<T>) value;
return values.stream().map(Enum::name).collect(Collectors.toList());
}
return ((Enum) value).name();
}
public Object toEntityAttribute(Object value) {
if (Collection.class.isAssignableFrom(value.getClass())) {
List<String> values = (List<String>) value;
return values.stream().map(v -> (T) T.valueOf(enumType, v)).collect(Collectors.toList());
}
return (T) T.valueOf(enumType, value.toString());
}
}
抽象转换器可以被所有枚举所化,并用作@Convert批注的参数:
public enum EnumType {
VALUE_A, VALUE_B;
public static class Converter extends SearchQueryEnumConverter<EnumType> implements AttributeConverter {
}
}
@NodeEntity
public Entity {
@Property
@Convert(EnumType.Converter.class)
EnumType type;
}