【问题标题】:How to deserialize a class with relational mapping?如何反序列化具有关系映射的类?
【发布时间】:2021-08-07 00:55:49
【问题描述】:

所以我正在尝试执行以下测试:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class PartyResultUserEndpointTest {
@Autowired
private MockMvc mockMvc;

@Test
@WithMockUser("Test User")
public void GetPartyResultUsers() throws Exception {
    MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/partyresults").accept("application/json"))
            .andExpect(status().isOk()).andReturn();

    String content = mvcResult.getResponse().getContentAsString();

    ObjectMapper mapper = new ObjectMapper();
    TypeFactory typeFactory = mapper.getTypeFactory();
    List<PartyResultUser> partyLeaderList = mapper.readValue(content, typeFactory.constructCollectionType(List.class, PartyResultUser.class));

    Assertions.assertNotNull(partyLeaderList);

}

问题是我一直收到这个错误:

Cannot construct instance of `org.springframework.security.core.GrantedAuthority` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

所以我在我的类中添加了以下代码行:

@JsonDeserialize(as = PartyResultUser.class)

所以他们看起来像这样:

党课:

@NoArgsConstructor
@Entity
@Table(name="party")
@Getter
@Setter
@JsonDeserialize(as = PartyResultUser.class)
public class Party {
    public Party(Integer id, String name, String description, Boolean ispartynational) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.ispartynational = ispartynational;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String description;
    private Boolean ispartynational;




    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "partyleaderid", referencedColumnName = "id")
    private PartyLeader partyLeader;

    @JsonIgnore
    @OneToMany(mappedBy = "party", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<CoalitionPartyUser> coalitionPartyUsers;


    @JsonIgnore
    @OneToMany(mappedBy = "party", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<PartyResultUser> partyResultUsers;

结果类:

@Entity
@Table(name = "result")
@Getter
@Setter
@NoArgsConstructor
@JsonDeserialize(as = PartyResultUser.class)
public class Result {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate date;

    @JsonIgnore
    @OneToMany(mappedBy = "result", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<PartyResultUser> partyResultUsers;

}

我的帐户类:

@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor//creates constructor without parameters
@Entity
/*@JsonIgnoreProperties(ignoreUnknown = true)*/
@JsonDeserialize(as = PartyResultUser.class)
public class Account implements UserDetails {

    @SequenceGenerator(
            name = "user_sequence",
            sequenceName = "user_sequence",
            allocationSize = 1
    )
    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "user_sequence"
    )


    private Integer id;
    private String username;
    private String email;
    private String password;
    @Enumerated(EnumType.STRING)
    private AccountUserRole accountUserRole;
    private Boolean locked = false;
    private Boolean enabled = false;

    @JsonIgnore
    @OneToMany(mappedBy="account")
    private Set<Coalition> coalitions;

    public Account(String username,String email, String password, AccountUserRole accountUserRole) {
        this.username = username;
        this.email = email;
        this.password = password;
        this.accountUserRole = accountUserRole;
    }
    @Override

    public Collection<? extends GrantedAuthority> getAuthorities() {
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority(accountUserRole.name());
        return Collections.singletonList(authority);
    }

但这给了我这个我似乎无法解决的错误:

Failed to narrow type [simple type, class com.example.demo.Model.Account] with annotation (value com.example.demo.Model.PartyResultUser), from 'com.example.demo.Model.Account': Class `com.example.demo.Model.PartyResultUser` not subtype of `com.example.demo.Model.Account`
com.fasterxml.jackson.databind.JsonMappingException: Failed to narrow type [simple type, class com.example.demo.Model.Account] with annotation (value com.example.demo.Model.PartyResultUser), from 'com.example.demo.Model.Account': Class `com.example.demo.Model.PartyResultUser` not subtype of `com.example.demo.Model.Account`

有人可以帮我解决我的问题吗? 提前感谢您的努力!

【问题讨论】:

    标签: java json spring-boot deserialization spring-test


    【解决方案1】:
    Cannot construct instance of `org.springframework.security.core.GrantedAuthority` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
    

    之所以发生,是因为杰克逊不知道如何反序列化与 getAuthorities 关联的 json 部分,尤其是如何创建 GrantedAuthority,因为 GrantedAuthority 说您应该将其映射到具体类型或具有自定义反序列化器

    你能注释 @JsonIgnore 方法 getAuthorities 吗?

    最新的异常

    Failed to narrow type [simple type, class com.example.demo.Model.Account] with annotation (value com.example.demo.Model.PartyResultUser), from 'com.example.demo.Model.Account': Class `com.example.demo.Model.PartyResultUser` not subtype of `com.example.demo.Model.Account` com.fasterxml.jackson.databind.JsonMappingException: Failed to narrow type [simple type, class com.example.demo.Model.Account] with annotation (value com.example.demo.Model.PartyResultUser), from 'com.example.demo.Model.Account': Class `com.example.demo.Model.PartyResultUser` not subtype of `com.example.demo.Model.Account`
    

    因为您正在注释而发生

    @JsonDeserialize(as = PartyResultUser.class)
    

    不是 PartyResultUser 超类的类

    所以你也应该删除这些注释

    【讨论】:

      猜你喜欢
      • 2020-07-02
      • 2021-09-18
      • 1970-01-01
      • 2020-10-12
      • 2015-03-27
      • 2017-07-11
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多