无法保存带有Map的Objectify实体在嵌入类中?

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

Unable to Save Objectify entity with Map<string,Object> in Embedded classes?

问题

我有一个嵌入式实体,其中有一个类型为Map<String, Object>的字段。

地图的所有键都是字符串类型。

以下是实体:

  1. @Entity
  2. @Index
  3. @Getter @Setter
  4. public class NiftySurveys {
  5. @Id
  6. private Long id;
  7. private List&lt;SurveyQuestions&gt; questions;
  8. private Long createddate;
  9. private Long updatedDate;
  10. }
  11. @Getter @Setter
  12. public class SurveyQuestions {
  13. private String label;
  14. private String code;
  15. private SurveyQuestionGroups questionGroup;
  16. private Map&lt;String,Object&gt; optionGroup;
  17. }

我在保存带有optionGroup的实体时遇到问题。

从前端提交的示例实体:

  1. {
  2. "questions": [{
  3. "label": "jio",
  4. "code": null,
  5. "questionGroup": {
  6. "name": "Date Time",
  7. "value": "DATI"
  8. },
  9. "optionGroup": {
  10. "labels": [{
  11. "label": "Date / Time"
  12. }],
  13. "collectDateInfo": true,
  14. "collectTimeInfo": true,
  15. "dateFormat": "MM/DD/YYYY",
  16. "validationMessage": "Please Enter a Valid Date!"
  17. }
  18. }, {
  19. "code": null,
  20. "label": "Q2",
  21. "questionGroup": {
  22. "name": "Multiple Choice Questions",
  23. "value": "MCQ"
  24. },
  25. "optionGroup": {
  26. "name": "Agree - Disagree",
  27. "code": "AGDAG",
  28. "options": [{
  29. "label": "YES",
  30. "value": "Y"
  31. }, {
  32. "label": "NO",
  33. "value": "N"
  34. }]
  35. }
  36. }]
  37. }

地图的所有键都是字符串类型。

错误消息:

  1. exception: "com.googlecode.objectify.SaveException"
  2. message: "Error saving com.nifty.niftyfeedbacks.domain.NiftySurveys@4ac88d5e: java.lang.IllegalStateException: Embedded Map keys must be of type String/Enum/Key&lt;?&gt; or field must specify @Stringify"

Stack Trace链接:
https://drive.google.com/file/d/1fqpPLiJutWLif5GnrlqLEZ6Wr_PdLdC-/view?usp=sharing

英文:

I have an embedded entity that has a Field of type Map<String, Object>.

All keys to the Map Are of type String.

Below is Entity

  1. @Entity
  2. @Index
  3. @Getter @Setter
  4. public class NiftySurveys {
  5. @Id
  6. private Long id;
  7. private List&lt;SurveyQuestions&gt; questions;
  8. private Long createddate;
  9. private Long updatedDate;
  10. }
  11. @Getter @Setter
  12. public class SurveyQuestions {
  13. private String label;
  14. private String code;
  15. private SurveyQuestionGroups questionGroup;
  16. private Map&lt;String,Object&gt; optionGroup;
  17. }

>I am having trouble saving Entity with optionGroup.

Sample Entity submitted From FrontEnd

  1. {
  2. &quot;questions&quot;: [{
  3. &quot;label&quot;: &quot;jio&quot;,
  4. &quot;code&quot;: null,
  5. &quot;questionGroup&quot;: {
  6. &quot;name&quot;: &quot;Date Time&quot;,
  7. &quot;value&quot;: &quot;DATI&quot;
  8. },
  9. &quot;optionGroup&quot;: {
  10. &quot;labels&quot;: [{
  11. &quot;label&quot;: &quot;Date / Time&quot;
  12. }],
  13. &quot;collectDateInfo&quot;: true,
  14. &quot;collectTimeInfo&quot;: true,
  15. &quot;dateFormat&quot;: &quot;MM/DD/YYYY&quot;,
  16. &quot;validationMessage&quot;: &quot;Please Enter a Valid Date!&quot;
  17. }
  18. }, {
  19. &quot;code&quot;: null,
  20. &quot;label&quot;: &quot;Q2&quot;,
  21. &quot;questionGroup&quot;: {
  22. &quot;name&quot;: &quot;Multiple Choice Questions&quot;,
  23. &quot;value&quot;: &quot;MCQ&quot;
  24. },
  25. &quot;optionGroup&quot;: {
  26. &quot;name&quot;: &quot;Agree - Disagree&quot;,
  27. &quot;code&quot;: &quot;AGDAG&quot;,
  28. &quot;options&quot;: [{
  29. &quot;label&quot;: &quot;YES&quot;,
  30. &quot;value&quot;: &quot;Y&quot;
  31. }, {
  32. &quot;label&quot;: &quot;NO&quot;,
  33. &quot;value&quot;: &quot;N&quot;
  34. }]
  35. }
  36. }]
  37. }

> All Keys of the map Are Strings.

Error Message:

  1. exception: &quot;com.googlecode.objectify.SaveException&quot;
  2. message: &quot;Error saving com.nifty.niftyfeedbacks.domain.NiftySurveys@4ac88d5e: java.lang.IllegalStateException: Embedded Map keys must be of type String/Enum/Key&lt;?&gt; or field must specify @Stringify&quot;

link to Stack Trace
https://drive.google.com/file/d/1fqpPLiJutWLif5GnrlqLEZ6Wr_PdLdC-/view?usp=sharing

答案1

得分: 1

要查看 @Stringify 的工作原理,请参阅 https://github.com/objectify/objectify/wiki/Entities#stringify

为了在 Maps 中使用非字符串键,您可以指定 @Stringify 注解:

  1. import com.googlecode.objectify.annotation.Entity;
  2. import com.googlecode.objectify.annotation.Id;
  3. import com.googlecode.objectify.annotation.Stringify;
  4. import com.googlecode.objectify.stringifier.Stringifier;
  5. class DateStringifier implements Stringifier<LocalDate> {
  6. @Override
  7. public String toString(LocalDate obj) {
  8. return obj.getString();
  9. }
  10. @Override
  11. public LocalDate fromString(String str) {
  12. return new LocalDate(str);
  13. }
  14. }
  15. @Entity
  16. class Car {
  17. @Id Long id;
  18. @Stringify(DateStringifier.class)
  19. Map<LocalDate, ServiceRecord> serviceHistory = new HashMap<>();
  20. }
英文:

To see how @Stringify works, look at https://github.com/objectify/objectify/wiki/Entities#stringify :

  1. In order to use non-String keys with Maps, you may specify the @Stringify annotation:
  2. import com.googlecode.objectify.annotation.Entity;
  3. import com.googlecode.objectify.annotation.Id;
  4. import com.googlecode.objectify.annotation.Stringify;
  5. import com.googlecode.objectify.stringifier.Stringifier;
  6. class DateStringifier implements Stringifier&lt;LocalDate&gt; {
  7. @Override
  8. public String toString(LocalDate obj) {
  9. return obj.getString();
  10. }
  11. @Override
  12. public LocalDate fromString(String str) {
  13. return new LocalDate(str);
  14. }
  15. }
  16. @Entity
  17. class Car {
  18. @Id Long id;
  19. @Stringify(DateStringifier.class)
  20. Map&lt;LocalDate, ServiceRecord&gt; serviceHistory = new HashMap&lt;&gt;();
  21. }

Previous response :
The error message is clear : you must provide a "String-way" to handle your embedded entity. So you should write a toString() method inside your embedded entity or use the @Stringify annotation as appropriate.

It seems to be JSON, so did you try to use @JsonUnwrapped :
@see https://stackoverflow.com/a/10077262/390462

  1. class Item {
  2. private String title;
  3. @JsonProperty(&quot;date&quot;)
  4. private Date createdAt;
  5. // How to map this?
  6. @JsonUnwrapped
  7. private Author author;
  8. }

You can go through a good JPA tutorial to handle Embedded objects too :

  1. https://examples.javacodegeeks.com/enterprise-java/jpa/jpa-embedded-embeddable-example/
  2. https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/embeddable-classes.html
  3. https://www.tutorialspoint.com/ejb/ejb_embeddable_objects.htm

答案2

得分: 0

使用@Serialize注解来处理复杂对象图。
来自Objectify文档

这解决了我的问题。

  1. @Getter @Setter
  2. public class SurveyQuestions implements Serializable{
  3. private static final long serialVersionUID = -6930992373082651231L;
  4. @Serialize
  5. private Map&lt;String,Object&gt; optionGroup;
  6. }
英文:

> Use @Serialize annotation for complex object graph.
From Objectify Docs

This Solved my issue.

  1. @Getter @Setter
  2. public class SurveyQuestions implements Serializable{
  3. private static final long serialVersionUID = -6930992373082651231L;
  4. @Serialize
  5. private Map&lt;String,Object&gt; optionGroup;
  6. }

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

发表评论

匿名网友

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

确定