Spring Data Neo4j自定义的@QueryResult不识别枚举。

huangapple go评论113阅读模式
英文:

Spring data neo4j custom @QueryResult doesn't recognize enums

问题

我正在尝试创建一个自定义的@QueryResult,其中包含来自不同节点的多个字段,但似乎查询结果机制无法正确映射枚举。

这是我为这种情况制作的示例。我创建了一个基本的枚举:

  1. public enum MyEnum{
  2. SOMETHING, SOMETHING_ELSE
  3. }

并在Spring Data Neo4j仓库方法中使用以下查询:

  1. @Query("MATCH (people:People)-[:LIVES_IN]->(country:Country) " +
  2. "RETURN people.enum")
  3. List<WithEnumQueryResult> findPeople();

当我触发它时,会抛出异常:

  1. org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate pl.degath.WithEnumQueryResult using constructor pl.degath.WithEnumQueryResult(pl.degath.MyEnum) with arguments SOMETHING_ELSE

通过反复试验,我发现以下内容:

  1. @Builder
  2. @Getter
  3. @QueryResult
  4. public class WithEnumQueryResult{
  5. private final MyEnum enum; //我希望拥有这个,但会抛出错误
  6. private final String enum; //这会将我的枚举返回为String(不会抛出错误)
  7. private final People people; //这个在people的属性中具有正确的枚举(不会抛出错误)
  8. }

我还尝试在枚举属性前添加一些@Converter注解,例如@Convert(EnumStringConverter.class),但没有帮助。

对于如何使我的QueryResult识别枚举,有什么想法吗?

编辑:

正如接受答案中的评论所提到的,似乎枚举需要无参构造函数,所以我不得不将我的不可变对象更改为:

  1. @Builder
  2. @Getter
  3. @NoArgsConstructor(access = AccessLevel.PRIVATE)
  4. @AllArgsConstructor
  5. @QueryResult
  6. public class WithEnumQueryResult{
  7. private MyEnum enum; //现在枚举可见!
  8. }
英文:

I'm trying to create a custom @QueryResult with multiple fields from different nodes, but it seems like the query result mechanism is unable to map enum correctly.

This is an example that I made for this scenario. I created a basic enum as:

  1. public enum MyEnum{
  2. SOMETHING, SOMETHING_ELSE
  3. }

And spring data neo4j repository method with the query:

  1. @Query(&quot;Match (people:People)-[:LIVES_IN]-&gt;(country:Country) &quot; +
  2. &quot;RETURN people.enum&quot;)
  3. List&lt;WithEnumQueryResult&gt; findPeople();

when I trigger it throws an exception:

  1. org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate pl.degath.WithEnumQueryResult using constructor pl.degath.WithEnumQueryResult(pl.degath.MyEnum) with arguments SOMETHING_ELSE

I was able to see through trial and error that:

  1. @Builder
  2. @Getter
  3. @QueryResult
  4. public class WithEnumQueryResult{
  5. private final MyEnum enum; //this one I would like to have, but throws error
  6. private final String enum; //this returns my enum as String (doesn&#39;t throw error)
  7. private final People people; //this one has correct enum as a property of people (doesn&#39;t throw error)
  8. }

I tried also add some @Converter e.g. @Convert(EnumStringConverter.class) annotation in front of my enum property, but it didn't help out.

Any ideas on how can I make my QueryResult recognize enums?

EDIT:

As mentioned in a comment from the accepted answer, it seems like enums require no-args constructors, so I had to change my immutable object into the:

  1. @Builder
  2. @Getter
  3. @NoArgsConstructor(access = AccessLevel.PRIVATE)
  4. @AllArgsConstructor
  5. @QueryResult
  6. public class WithEnumQueryResult{
  7. private MyEnum enum; //enum is visible now!
  8. }

答案1

得分: 1

以下是我的实体类和存储库,它们完美地运行正常。

  1. @Data
  2. @QueryResult
  3. public class PersonResponse {
  4. private Long id;
  5. private String name;
  6. private int age;
  7. private City livesAt;
  8. private Test test;
  9. private List<Person> friends;
  10. }
  11. public enum Test {
  12. A, B
  13. }

存储库方法:

  1. @Query("MATCH (pr:Person) where ID(pr)=$id return ID(pr) as id, pr.test as test, pr.name as name, pr.age as age")
  2. public PersonResponse getPerson(Long id);

结果:

  1. {
  2. "id": 68,
  3. "name": "Alex",
  4. "age": 24,
  5. "test": "A"
  6. }
英文:

Below are my entity classes and repository which perfectly works fine.

  1. @Data
  2. @QueryResult
  3. public class PersonResponse {
  4. private Long id;
  5. private String name;
  6. private int age;
  7. private City livesAt;
  8. private Test test;
  9. private List&lt;Person&gt; friends;
  10. }
  11. public enum Test {
  12. A, B
  13. }

Repository method

  1. @Query(&quot;MATCH (pr:Person) where ID(pr)=$id return ID(pr) as id, pr.test as test, pr.name as name, pr.age as age&quot;)
  2. public PersonResponse getPerson(Long id);

Result:

  1. {
  2. &quot;id&quot;: 68,
  3. &quot;name&quot;: &quot;Alex&quot;,
  4. &quot;age&quot;: 24,
  5. &quot;test&quot;: &quot;A&quot;,
  6. }

huangapple
  • 本文由 发表于 2020年10月20日 20:17:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/64444991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定