2012-11-26 70 views
1

我正在使用Java EE JSP/EJB3,並且在執行表之間的關係時遇到問題。最初我在考慮存儲這個id,但是我讀過它會打敗存儲對象引用的EJB的目的EJB3映射/ onetomany/manytoone如何處理關係

作爲一個解釋我的問題的測試示例,我提出了一個汽車模型和汽車品牌關係。在此Web應用程序中用戶首先創建品牌。然後創建汽車並從下拉列表中選擇品牌。

汽車 - >蘭特:多對一 品牌 - >汽車:一對多

public class Brand implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id") 
    private long id; 

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

    @Column(name="cars_fk") 
    private Set<Car> cars; 
... 

} 

以下是該車的EntityBean

public class Car implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id") 
    private long id; 

    private Brand brand; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @Column(name="brand_FK") 
    private Brand brand; 
... 

} 

鑑於上面是正確的(我我不確定)

什麼是處理這些輸入的最佳實踐

可以說我有這個網站(如果選擇必須是不同的,請不要告訴)

<form action="processCar.jsp"> 
    Model: <input type="text" name="title"><br> 

    <select> 
    <option value="volvo">Volvo</option> 
    <option value="saab">Saab</option> 
    <option value="mercedes">Mercedes</option> 
    <option value="audi">Audi</option> 
    </select> 

    <input type="submit" value="Submit"> 
</form> 

選項從Brand.findAll加載的品牌。

此外,如果這是正確的,從品牌名稱/ ID到實體對象品牌的轉換是從哪裏完成的?在會話bean?

public void createCar(String title,String brandname){ 
    Query query = em.createNamedQuery("Brand.getBrandbyName"); 
    query.setParameter("brand_name", brandname); 
    Brand brand = (Brand)query.getSingleResult(); 
    carSLSBManagement.create(title,brand); 
} 

在此先感謝

+0

您在'Brand'中的'cars'字段的聲明看起來不正確。它是'@ OneToMany',這意味着它不能使用'@ Column',因爲在實體的表中不會有單列。相反,你應該說'@OneToMany(mappedBy =「品牌」)',並且由'Car'實體的表中的'brand'字段驅動。 –

回答

0

通常的方式做,這是使用的ID在下拉的值,然後把它儘快轉換爲對象儘可能代碼接收請求。這將是一個servlet或等價物,而不是一個bean。這個bean應該可以處理已經被獲取的對象。

如果你有品牌的ID,然後取這很簡單,只要:

long brandId = Long.parseLong(request.getParameter("brandId")); 
Brand brand = em.find(Brand.class, brandId); 

我會補充說,儘管我的偏好是做所有的參數解析和解碼在網絡層,前進入領域層,由於技術原因,您可能會更方便地將其中的一部分向下推入領域層。例如,在執行em.find時應該打開一個事務,並且如果您將經典Java EE體系結構與servlet和EJB一起使用,那麼事務自然會在EJB上開始,而且這些servlet是非事務性的。爲了適應這一點,你可以在servlet中將ID解析爲一長串,但是在EJB中獲取對象。這有點笨拙,但這確實意味着你不必與交易混淆。

+0

爲什麼你儘快獲取它?我認爲理想情況下應該在ejb層上進行entitybean操作。保持戰爭層級和ejb層級之間的戰鬥力。如我錯了請糾正我。 – SGalea

+0

我相信最好儘快從原始字符串到真實對象,以確保類型安全和一致地使用域概念。我認爲沒有任何特別的理由將數據庫操作限制在EJB層上;我認爲這是對EJB 1和2過去糟糕的規定性,架構優先習慣的回味。請記住,持久化對象不再是「實體bean」,它們只是對象! –

+0

使用實體代替DTO意味着您必須直接從Web應用程序或通過本地ejb訪問實體管理器。這會稍微增加攻擊面。然而,使用DTO會增加開發時間,遠程處理會造成性能損失。 –