休眠持续单向一对多关系

时间:2018-08-09 21:04:36

标签: hibernate jpa hibernate-onetomany

我有以下模型:

enter image description here

对应的映射如下:

报价实体

@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;
}

项目实体

@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;
}

我遇到的问题是我无法使用项目列表来保留报价,这是我尝试执行的代码:

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();

我收到以下错误:

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)

鉴于以上所述,这让我开始思考...如何使自动休眠可以将Quote及其项目保留下来。为什么不休眠首先生成Quote的ID,将其保留,然后再保留Items? 我应该如何进行映射以保持单向关系,并且我可以毫无困难地完成我正在尝试的工作?

非常感谢!

3 个答案:

答案 0 :(得分:0)

映射问题中显示的数据库模型的正确方法如下:

报价实体

@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;
}

项目实体

@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;

}

以及用于保留带有实体的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();
item2.setName("Item 2");

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

quote.setItem(items);

session.persist(quote);

session.getTransaction().commit();

答案 1 :(得分:0)

Hibernate提供了双方映射,以实现灵活的代码。 如果要从有价值的实体(项目)执行任何操作。 做正确的映射

1)Quote.java类

func(tv T, a int) int

2)在Item.java类内部

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

private Set<Item> item;

答案 2 :(得分:-1)

尝试

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

在您的情况下,无法成功,因为您无法在此处设置关系:如果满足以下条件,它将起作用(并且仍然非常糟糕):

删除级联= 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);