简体   繁体   English

休眠持续单向一对多关系

[英]Hibernate Persist Unidirectional One To Many Relationship

I have the following model: 我有以下模型:

在此处输入图片说明

The corresponding mapping is as follows: 对应的映射如下:

Quote entity 报价实体

@Entity
@Table(name="Quote")
@Getter
@Setter
public class Quote {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="idQuote")
    private int id;

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

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name="Quote_idQuote")
    private Set<Item> item;
}

Item Entity 项目实体

@Entity
@Table(name="Item")
@Getter
@Setter
public class Item {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="idItem")
    private int id;

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

    @Column(name="Quote_idQuote")
    private int quoteId;
}

The problem I have is that I can not persist a Quote with a list of Items, this is the code where I try to do it: 我的问题是我无法使用项目列表来保留Quote,这是我尝试执行的代码:

SessionFactory sessionFactory;
Configuration configuration= new Configuration();
configuration.configure();
sessionFactory=configuration.buildSessionFactory();
Session session= sessionFactory.openSession();
session.beginTransaction();

Quote quote= new Quote();
quote.setNumber("ASR3E4E");

Set<Item> items= new HashSet<Item>();

Item item1= new Item();
item1.setName("Item 1");

Item item2= new Item();
item1.setName("Item 2");

items.add(item1);
items.add(item2);        

quote.setItem(items);

session.persist(quote);

session.getTransaction().commit();

I get the following error: 我收到以下错误:

Hibernate: insert into Quote (number) values (?)
Hibernate: insert into Item (name, Quote_idQuote) values (?, ?)
Aug 09, 2018 3:27:25 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1452, SQLState: 23000
Aug 09, 2018 3:27:25 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Cannot add or update a child row: a foreign key constraint fails (`test`.`item`, CONSTRAINT `fk_Item_Quote` FOREIGN KEY (`Quote_idQuote`) REFERENCES `quote` (`idquote`))
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:831)

Given the above, it makes me think... How to do so that automatically hibernate can persist the Quote with its Items. 鉴于以上所述,这让我开始思考...如何做到这一点,以便自动休眠可以将Quote及其项目持久化。 Why doesn't hibernate first generate the id of the Quote, persist it, and then, persists a Items? 为什么不休眠首先生成Quote的ID,将其保留,然后再保留Items? How should I do the mapping to maintain a unidirectional relationship and that I can do what I'm trying without problems? 我应该如何进行映射以保持单向关系,并且我可以毫无问题地完成我想做的事情?

Many Thanks! 非常感谢!

The correct way to map the database model shown in the question is as follows: 映射问题中显示的数据库模型的正确方法如下:

Quote entity 报价实体

@Entity
@Table(name="Quote")
@Getter
@Setter
public class Quote {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="idQuote")
    private int id;

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

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "Quote_idQuote", nullable=false)
    private Set<Item> item;
}

Item entity 项目实体

@Entity
@Table(name="Item")
@Getter
@Setter
public class Item {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="idItem")
    private int id;

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

}

And the code to persist Quote entity with Items: 以及用于使用Quotes持久引用实体的代码:

SessionFactory sessionFactory;
Configuration configuration= new Configuration();
configuration.configure();
sessionFactory=configuration.buildSessionFactory();
Session session= sessionFactory.openSession();
session.beginTransaction();

Quote quote= new Quote();
quote.setNumber("ASR3E4E");

Set<Item> items= new HashSet<Item>();

Item item1= new Item();
item1.setName("Item 1");

Item item2= new Item();
item2.setName("Item 2");

items.add(item1);
items.add(item2);        

quote.setItem(items);

session.persist(quote);

session.getTransaction().commit();

Hibernate provide both side mapping for a flexible code. Hibernate提供了双方映射,以实现灵活的代码。 If you want to do any operation from valued entity(item). 如果要从有价值的实体(项目)执行任何操作。 Do correct mapping 做正确的映射

1) Quote.java class 1)Quote.java类

    @OneToMany(cascade = CascadeType.ALL, mappedBy="quote",fetch=FetchType.Eager)

private Set<Item> item;

2) Inside Item.java class 2)在Item.java类中

    @ManyToOne
    @JoinColumn(name="Quote_idQuote") 
    private Quote quote;  

Try 尝试

   item1.setQuote(quote);
   item2.setQuote(quote);
   session.persist(quote);

In your case it is impossible to succed as you cannot set relations here: It would work (and still be very bad) if: 在您的情况下,无法成功,因为您无法在此处设置关系:如果满足以下条件,它将起作用(并且仍然非常糟糕):

remove cascade = CascadeType.ALL, 删除级联= CascadeType.ALL,

session.persist(quote); // this must be done first to actually get bloody quote ID that you can propagate
item1.setQuoteId(quote.getId()); //or something to set quoteid
item2.setQuoteId(quote.getId())=quote.id; //or something to set quoteid
session.persist(item1);
session.persist(item2);

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

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