【问题标题】:jsf - foreign key in datatablejsf - 数据表中的外键
【发布时间】:2015-06-13 22:43:50
【问题描述】:

我在数据表中显示订单列表,其中一列必须显示该订单的 customer_id:customer_id 是 ManyToOne 关系中的 fk。

客户实体

@Entity
public class Customer {

    ///other columns

    @OneToMany(mappedBy = "cliente", fetch=FetchType.EAGER)
    private List<Order> orders;

订单实体

    @Entity
@Table(name = "orders")

public class Order implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;


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


    @Column (nullable = false)
    private String state;

    @Column (nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar openingDate;

    @Column (nullable = true)
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar closingDate;

    @Column (nullable = true)
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar evadingDate;

    @ManyToOne(cascade={ CascadeType.PERSIST, CascadeType.REMOVE },fetch=FetchType.LAZY)
    @JoinColumn(name = "customer_id") 
    private Customer customer;

最后,这是我将包含所有订单的数据表放入的页面。

showOrders.xhtml

<h:dataTable id="list" value="#{orderController.orders}"
        var="order">
        <h:column>
            <f:facet name="header">Nome</f:facet>
            <h:commandLink action="#{orderController.findOrder}"
                value="#{order.id}" style="color: orange">
                <f:setPropertyActionListener target="#{orderController.id}"
                    value="#{order.id}" />
            </h:commandLink>
        </h:column>
        <h:column>
            <f:facet name="header">Stato</f:facet>
            <h:outputText value="#{order.state}" />
        </h:column>
        <h:column>
            <f:facet name="header">Data Apertura</f:facet>
            <h:outputText value="#{order.openingDate.time}">
                <f:convertDateTime datestyle="full" type="date" />
            </h:outputText>
        </h:column>
        <h:column>
            <f:facet name="header">Data Chiusura</f:facet>
            <h:outputText value="#{order.closingDate.time}">
                <f:convertDateTime datestyle="full" type="date" />
            </h:outputText>
        </h:column>
        <h:column>
            <f:facet name="header">Data Evasione</f:facet>
            <h:outputText value="#{order.evadingDate.time}">
                <f:convertDateTime datestyle="full" type="date" />
            </h:outputText>
        </h:column>
        <h:column>
            <f:facet name="header">ID Cliente</f:facet>
            <h:commandLink action="#{registerCustomer.detailsCustomer}"
                value="#{order.customer.id}" style="color: orange">
                <f:setPropertyActionListener target="#{registerCustomer.id}"
                    value="#{order.customer.id}" /> 
            </h:commandLink>
        </h:column>

问题是,除了 customer_id 没有显示在页面上之外,一切都很好。我做错了什么? 我已经尝试了很多东西,改变了获取类型,改变了关系......但我开始认为这是一个 java 问题,即使我在互联网上无法真正找到解决方案或一些解释。有人可以帮助我吗?我被困住了:/

【问题讨论】:

  • 你在哪里显示customer_id?是这里value="#{order.customer.id}"吗?该字段被延迟获取(FetchType.LAZY)。您可能需要预取,但对于如何获取与特定客户关联的订单列表是完全不可见的。此外,在@ManyToOne 关系上设置CascadeType.REMOVE 没有意义。每当删除其中一个子项时,它将删除关联的父项(Customer 行)。因此,根据表中外键列上设置的级联类型,其剩余的孩子可能会成为孤儿。
  • @Tiny 没错,我想在那里显示它,但它没有。您是说我应该将获取更改为渴望吗?顺便说一句,我现在会清除“CascadeType.REMOVE”,不知道它为什么会在那里(不幸的是我正在和另一个人一起工作,所以不是整个代码都是我的)
  • 不。不必要地使用FetchType.EAGER 是有史以来最糟糕的情况。根据给定问题的描述猜测确切的症状是困难的。你确定#{order.customer.id} 的值吗?它的值可能已正确获取,但由于某些不清楚的原因,它没有正确设置为与 &lt;f:setPropertyActionListener&gt; 关联的托管 bean 属性,即 target="#{registerCustomer.id}"
  • @Tiny 我不知道是不是这样,但无论如何&lt;f:setPropertyActionListener&gt; 用于传递参数并执行bean 的detailsCustomer 方法。主要问题是我什至看不到数据表上的客户 ID 值
  • @Enduavon 你有 customer_id 的 set 和 get 方法:getCustomer 和 setCustomer 吗?

标签: jpa datatable


【解决方案1】:

由于您的 OrderCustomer 相关,因此您需要执行以下操作才能继续使用 LAZY 加载但能够初始化给定订单的客户

        session = HibernateUtil.getSessionFactory().getCurrentSession();

        session.beginTransaction();
        ord = (Order) session.get(Order.class, id_order);
        Hibernate.initialize(ord.getCustomer());
        session.getTransaction().commit();
        Customer cust = ord.getCustomer();

还要检查您是否拥有该集合并与 customer_id JOIN 相关

Customer getCustomer() { }
setCustomer(Customer cust) { }

【讨论】:

  • 你好毛里西奥,谢谢你的回答。我没有使用 Hibernate,而是使用 EJB 连接到数据库。我怎样才能用@EJB 编写这个方法以及它究竟做了什么?
  • Enduavon:您将“EJB”与“JPA”混淆了。 Mauricio:您将“(Legacy) Hibernate Core”与“Hibernate EntityManager”混淆了。
  • 是的,对不起@BalusC,但我知道区别:) 顺便说一句,你应该知道我做错了什么。有什么想法吗?
  • 我只知道这不是 Java/JSF 问题。在从 EJB 检索 order.getCustomer().getId() 之后,在 JSF 呈现它之前直接打印/记录它时,您可能会遇到完全相同的问题(即 JSF 只是这里的“演示者”,它不会以任何方式操纵检索到的模型)。我建议减少问题中的 JSF 滋扰,并从 [jsf] 重新定位到 [jpa] 以使其更加集中。
  • 你应该看看你的问题是否已经在这里解决了stackoverflow.com/search?q=many+to+many+jsf,如果没有,你需要创建一个新问题。
【解决方案2】:

我很高兴地说我找到了解决方案! (感谢@Mauricio Gracia 启发我寻找解决方案的路径)

首先,我从 Order 类的客户关系中删除了“fetch = FetchType.LAZY”

@ManyToOne(cascade={CascadeType.PERSIST})
@JoinColumn(name = "customer_id") 
private Customer customer;

然后,我序列化了 Customer 类

   @Entity
public class Customer implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

一切正常,我可以在我的 .xhtml 页面中看到客户 ID :)) 但是,我不知道这是否是一个好的做法,但我认为我可以在这样的小型大学项目中冒险!谢谢大家

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多