2016-12-13 35 views
0

我有以下的数据库,它允许用户在书店租书: enter image description here如何在建立强制关系时建立弹簧jpa /正确的资料库?

实体类书籍需要保存时,有一个类别以及BookDescription。

那些书类看起来是这样的:

@Entity 
@Table(name = "books") 
@Inheritance(strategy = InheritanceType.JOINED) 
public abstract class Book { 

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
@JoinColumn(name = "book_description_id") 
private BookDescription bookDescription; 

@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) 
private Category category; 

//omitted fields, getters, setters & other relations 
} 

我被检查出春的数据JPA。它有

CrudRepository<T, ID extends Serializable> 

的签名,这意味着我将有

CrudRepository<Book, String> 

,但我将如何节省一本书吗?因此,一般来说,用户将提交一个表单,我将绑定一个BookUIObject,它将包含保存图书所需的所有详细信息,并将其传递给一个BookService女巫将从其中提取3个对象:Book(一个特定的实现),类别和BookDescription。现在的问题是将服务挂钩了书的关系,并呼吁广大repository.save(书)或它会调用像repository.save(图书,类别,BookDescription)的方法?

而且,我应该直接从用户的数据绑定到实体类,或做就像我说的,绑定到一般BookUIObject,让服务从中提取的实体类?

亲切的问候,

回答

2

通常你将不得不打电话BookReporitory.save(书)。 Book has cascaring坚持这两种关系,所以如果您在保存的book实例上设置了BookDescription和Category,它们也将被保留。如果你没有级联持久化,你将不得不使用它们的JPARepository保存它们(除非它们已经存在于Persistence上下文中)。

有一两件事是重要的,这个例子就明白的是,如果你创建一个新的类别对象,并将其放在一本书,并保存这本书是在数据库中创建一个新的类别。因此,如果UI职位类别= SIC-Fi,您必须检查是否类别已经存在,如果这样做,那么你必须使用的管理类别,并设置书上,而不是创建另一个“科幻”的范畴。这是我不会有级联坚持对类别关系,因为我宁愿有一个约束冲突,因为一个类别没有存在的理由,而不是一个新的类别科幻如果当有人怀念在UI拼写它。

我不建议将表单直接绑定到JPA实体,因为您总是需要从JPA中获取实体,因为您必须使用托管版本,所以根据我的经验,最好还有另一组用于表单绑定的bean 。

即跳出另一件事,如果缺乏可空=在@JoinColumn假。如果一本书不能存在而不在一个类别中,则将其传递给数据库至关重要,并且如果从JPA元数据模型生成表格,则这是如何完成的。如果我在使用数据库/ JPA时只能给出一个建议,那么就会过于热衷于使用NOT NULL。插入时获得约束冲突的时间比获得NullPointerException异常容易100倍,并且必须检查每个可能的代码路径,最终可能会调用save并检查参数是否为null。

此外,我建议您设置一些时间来理解EntityManager和持久性上下文的概念,大多数开发人员会犯的错误/假设回到持久性上下文以及4个实体状态如何工作。