繁体   English   中英

如何根据父级动态生成 JPA Id 列?

[英]How do I dynamically generate JPA Id column based on parent?

我有一个看起来像这样的 JSON 文件......

{
  "accountId": "123",
  "parties":[
    {
      "name": "John Doe"
    }
  ]
}

我可以使用类似的东西来解析这个很好

public class Account{
  private String id;
  @JsonProperty("parties")
  private List<Party> parties;
}

public class Party{
  private String name;
}

但是,SQL 表 PARTY 包含一个复合键作为 ID。 这是名称和父帐户 ID 的复合键。 有没有办法在没有单独课程的情况下做到这一点? 我试过这个...

@JsonBackReference
private Account parent;

public class GetIdConverter implements AttributeConverter<String, String> {
    @Override
    public String convertToDatabaseColumn(String b) {
        if(parent == null){
            logger.error("couldn't find the parent");
        }
        return parent.getId();
    }

    @Override
    public String convertToEntityAttribute(String s) {
        return s;
    }
}

但是当我尝试插入时,我得到...

IdentifierGenerationException:必须在调用 save() 之前手动分配此 class 的 ID

不幸的是,在 JPA 中定义复合键只有两个选项: @IdClass@EmbeddedId注释,在这两种情况下我们都必须创建一个单独的 class。 为复合 class 创建 class 背后的基本思想是了解我们的键包含多个主键字段并将此 object 视为原子。 将复合键作为 class 的想法使得在实现 JPA 的任何结构中使用实体键变得容易。

像选项一样,您可以将两个类合并为一个实体:

@Entity
@Table
@IdClass(PartyEntity.PartyId.class)
public class PartyEntity {

    public static class PartyId implements Serializable {
        private String accountId;

        private String name;

        public PartyId() {
        }

        public PartyId(String accountId, String name) {
            this.accountId = accountId;
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof PartyId)) return false;
            PartyId partyId = (PartyId) o;
            return Objects.equals(accountId, partyId.accountId) &&
                    Objects.equals(name, partyId.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(accountId, name);
        }
    }

    @Id
    private String accountId;

    @Id
    private String name;

    //getters and setters
}

对保护者的回答略有改进 - 您可以尝试以下映射:

public class Account{
  private String id;

  @JsonProperty("parties")
  @JsonManagedReference
  private List<Party> parties;
}

@IdClass(PartyEntity.PartyId.class)
public class Party {

    @JsonBackReference
    @Id
    @ManyToOne
    private Account account;


    @Id
    private String name;
}

请参阅规范的“派生标识符示例”部分中的第一个示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM