Нулевые значения вставляются в поля внешнего ключа в Hibernate - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть Question Сущность и Tag сущность с геттером, методами установки и отношением OneToMany от question до tag и отношением OneToOne от question до user

public class Question {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name="title")
    private String title;

    @Column(name="body")
    private String body;

    @Temporal(TemporalType.DATE)
    @Column(name="date_created")
    private Date date_created;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="user_id")
    private User user;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name="tag_id")
    private Tag tag;

    @Column(name="answer_count")
    private int answer_count;

    @Column(name="view_count")
    private int view_count;

    public Question() {

}

Тег сущности

public class Tag {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name="name")
    private String name;

    @Column(name="username")
    private String username;

    @Temporal(TemporalType.DATE)
    @Column(name="date_created")
    private Date date_created;

    public Tag() {

}

Когда я пытаюсь вставить вопрос, используя Почтальон, со следующими данными:

{
    "title": "stefanyyyxx",
    "body": "stefandoyee44",
    "date_created": "2019-02-27",
    "user_id" : 1,
    "tag_id": 1,
    "answer_count": 0,
    "view_count": 0
}

QuestionRepository.java:

@Override
public void save(Question theQuestion) {

    // get the current hibernate session
    Session currentSession = entityManager.unwrap(Session.class);

    // save employee
    currentSession.saveOrUpdate(theQuestion);
}

Нулевые значения вставляются для user_id и tag_id, хотя я использовал JoinColumn().

MySQL:

enter image description here

Ответы [ 3 ]

0 голосов
/ 28 февраля 2019

Вы должны добавить referencedColumnName в столбце внешнего ключа дочернего объекта

referencedColumnName="your primaray key column name"

РЕДАКТИРОВАТЬ:

referencedColumnName

  • Имя столбца, на который ссылается этот столбец внешнего ключа.
  • При использовании с сопоставлениями отношений сущностей, кроме описанных здесь случаев, указанный столбец находится в таблице целевого объекта.
  • При использовании с однонаправленным отображением внешнего ключа OneToMany указанный столбец находится в таблице исходной сущности.
  • При использовании внутри аннотации JoinTable ссылочный столбец находится в таблице объектов принадлежащей сущности.или обратный объект, если объединение является частью определения обратного объединения.
  • При использовании в отображении CollectionTable указанный столбец находится в таблице объекта, содержащего коллекцию.
  • По умолчанию (применяется только в том случае, если используется один столбец соединения): то же имя, что и столбец первичного ключа в указанной таблице.

Актив - родительская сущность, а AssetDetails - дочерняя сущность. Здесь я взял отношения OneToOne

Asset.java

@Entity
@Table(name="asset")
public class Asset {

    @Id
    @GeneratedValue
    @Column(name="assetid")
    private BigInteger assetid;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "asset")
    @JsonBackReference
    private AssetDetails assetDetails;

     public AssetDetails getAssetDetails() {
        return assetDetails;
    }

    public void setAssetDetails(AssetDetails assetDetails) {
        this.assetDetails = assetDetails;
        assetDetails.setAsset(this);
    }

    public Asset(your fields, AssetDetails assetDetails) {
        super();
        // your fields
        this.assetDetails = assetDetails;
        this.assetDetails.setAsset(this);
    }

    public Asset() {
        super();
    }

    public BigInteger getAssetid() {
        return assetid;
    }

    public void setAssetid(BigInteger assetid) {
        this.assetid = assetid;
    }
}

AssetDetails.java

@Entity
@Table(name="assetDetails")
public class AssetDetails {

    @Id
    @GeneratedValue
    private BigInteger assetdetailid;

    @JoinColumn(name = "assetid",nullable = false, updatable = false,referencedColumnName="assetid")
    @OneToOne(cascade=CascadeType.ALL)
    @JsonManagedReference
    private Asset asset;

    public Asset getAsset() {
        return asset;
    }

    public void setAsset(Asset asset) {
        this.asset = asset;
    }

    public AssetDetails(your fields,Asset asset) {
        super();
        //your fields
        this.asset = asset;
    }   
}
0 голосов
/ 28 февраля 2019

Как предложил @Karol Dowbecki,

преобразует объект JSON в DTO и использует этот DTO для получения User, Tag сущностей из соответствующих репозиториев .

Наконец, создайте объект сущности Вопрос и сохраните его.

Сущность Вопроса

@Entity
@Table(name = "question")
public class Question {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "title")
    private String title;

    @Column(name = "body")
    private String body;

    @Temporal(TemporalType.DATE)
    @Column(name = "date_created")
    private Date dateCreated;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private User user;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "tag_id")
    private Set<Tag> tag;

    @Column(name = "answer_count")
    private int answerCount;

    @Column(name = "view_count")
    private int viewCount;

}

Сущность пользователя

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

}

Tag Entity

@Entity
@Table(name = "tag")
public class Tag {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "username")
    private String username;

    @Temporal(TemporalType.DATE)
    @Column(name = "date_created")
    private Date dateCreated;

}

Класс DTO

public class QuestionDTO {

    private Long id;

    private String title;

    private String body;

    private Date dateCreated;

    private Long user;

    private Long tag;

    private int answerCount;

    private int viewCount;
}

Тестовый класс

@Service
public class TestService {

    @Autowired
    private QuestionRepository questionRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TagRepository tagRepository;

    public void addQuestion(QuestionDTO dto) {
        Tag tag = null;
        User user = null;
        Question question = null;

        Set<Tag> tags = null;

        tag = tagRepository.findById(dto.getTag());

        tags = new HashSet<>();
        tags.add(tag);

        user = userRepository.findById(dto.getUser());

        question = new Question();
        question.setTag(tags);
        question.setUser(user);
        question.setId(dto.getId());
        question.setBody(dto.getBody());
        question.setTitle(dto.getTitle());
        question.setViewCount(dto.getViewCount());
        question.setAnswerCount(dto.getAnswerCount());
        question.setDateCreated(dto.getDateCreated());

        questionRepository.save(question);

    }
}

ПРИМЕЧАНИЕ : Соотношение между Question и Tag в OneToMany, вы должны использовать тип Collection.

0 голосов
/ 28 февраля 2019

У вас несоответствие между JSON и @Entity структурой.JSON содержит числовые идентификаторы, а @Entity содержит фактические объекты, представляющие отношения.Скорее всего, вам следует ввести отдельный класс DTO для сопоставления этого JSON, тогда как в @Repository вы должны загружать User и Tag объекты на основе их идентификаторов или создавать новые.У вас уже есть CascadeType.ALL, поэтому Hibernate будет каскадно выполнять операцию постоянства.

Обычно уровень контроллера должен быть отделен от уровня хранилища, если вы не делаете что-то очень, очень простое.Это помогает развивать сервис без изменения контракта API, например, добавляя новые столбцы для аудита изменений.Выставив @Entity в качестве DTO, вы усложните свою жизнь в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...