2016-04-15 4 views
0

У меня есть две сущности User и Candidat, где Candidat расширяет класс User, следующим образом:как сохранить объект с DiscriminatorValue

пользователя объекта:

@Entity 
@Table(name="users") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="TYPE_USER",discriminatorType=DiscriminatorType.STRING,length=2) 

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,property="type") 
@JsonSubTypes({ 
    @Type(name="UC",value=Candidat.class) 
}) 

@XmlSeeAlso({Candidat.class}) 
public class User implements Serializable { 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Long codeUser; 
//other code ... 

Кандидат лицо:

@Entity 
@DiscriminatorValue("UC") 
@XmlType(name = "UC") 
public class Candidat extends User { 
    private String codeMassar; 

и сохранить новый кандидат Я называю этот метод репозитория:

candidatRepository.save() 

от:

public interface CandidatRepository extends JpaRepository<Candidat, String> { 

} 

Это моя служба остальное, что вызывает метод сохранения:

@RequestMapping(value = "/candidats", method = RequestMethod.POST) 
public Candidat saveCandidat(@RequestBody Candidat candidat) throws Exception { 
    return candidatMetier.saveCandidat(candidat); 
} 

Проблема это когда я хочу сохранить новый Кандидат следующим образом:

{ 
    "username": "User", 
    "password": "123456", 
    "email": "[email protected]" 
} 

Я получаю сообщение об ошибке сказав:

Не удалось прочитать HTTP сообщение: org.springframework.http.converter.HttpMessageNotReadableException: Не удалось прочитать документ: Неожиданный маркер (END_OBJECT), ожидаемый FIELD_NAME: Отсутствующий недвижимость «типа», который должен содержать идентификатор типа (для класса org.capvalue.fme.domain.Candidat)

То, что я понял из него, что я должен указать тип в объекте JSON Я представляемый, но я не думаю, что это необходимо, потому что я сохраняю новый Candidat который имеет @DiscriminatorValue("UC"), поэтому, когда его save в таблице User он будет автоматически сохранен с type='UC'.

Как я могу это решить?

+0

Попробуйте комментировать '@ JsonTypeInfo' и' @ JsonSubTypes' .. –

ответ

1

что я понимаю от него, что я должен указать тип в объекте JSON Я посылаю

Поскольку вы добавили @JsonTypeInfo, вы должны указать фактический класс экземпляров объекта используя поле type. Например, если вы установите поле type на номер UC, Джексон создаст экземпляр класса Candidat.

, но я не думаю, что это необходимо, потому что я сохраняю новый кандидат, который имеет @DiscriminatorValue («UC»), поэтому, когда его сохранить в таблице User будет сохранен с типом = «UC» автоматически.

@DiscriminatorValue будет обработан вашим поставщиком JPA. Напротив, @JsonTypeInfo - концепция Джексона, поэтому Нет!Вы не можете ожидать, что ваш JPA @DiscriminatorValue поможет Джексону определить фактический тип экземпляров объекта.

Вы должны либо отправить type информацию в JSON представления или удалить @JsonTypeInfo и @JsonSubTypes из вашего User класса. Я думаю, удаление аннотаций типа Джексона лучший подхода, так как вы используете фактические подклассы:

public Candidat saveCandidat(@RequestBody Candidat candidat) { ... } 

Кроме того, попытайтесь определить некоторые DTO с и вернуть их в качестве REST возвращаемых значений конечной точки. Одним из преимуществ такого подхода является то, что ваши метаданные Jackson и JPA разделены, поэтому вы избегаете этих проблем.

+0

Спасибо, теперь я понимаю проблему, поэтому в данном случае я не могу просто указать тип в служебном коде без указания его с клиентской стороны? –

+0

Да, вы должны это сделать. Ибо вы не используете 'JsonTyeInfo' совершенно правильно, и его лучше удалить. –

+0

Я не мог найти способ указать тип в служебном коде при сохранении нового кандидата, поскольку это поле представлено только в базе данных. –

Смежные вопросы