Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅当服务器重新启动时,JPA急取才起作用_Jpa_Glassfish_Fetch_Restart_Eager - Fatal编程技术网

仅当服务器重新启动时,JPA急取才起作用

仅当服务器重新启动时,JPA急取才起作用,jpa,glassfish,fetch,restart,eager,Jpa,Glassfish,Fetch,Restart,Eager,大家晚上好,这是我关于堆栈溢出的第一篇文章。 我最近被介绍到Java6EE,特别是作为JSF2.1框架的一部分介绍到JPA,我现在面临一个奇怪的行为,我希望您能帮助我理解。 在我们的项目(使用NetBeans 7.2开发)中,我们有多个一对多关系,我们希望以与多对一导航相同的方式导航它们。事实上,只有在重启应用服务器(Glassfish 3.1.2)之后,我们才能让它们按照我们的意愿工作,而且,这种行为只会持续到下一次部署;这意味着我们每次应用修改时都需要重新启动Glassfish。。。 下面是

大家晚上好,这是我关于堆栈溢出的第一篇文章。 我最近被介绍到Java6EE,特别是作为JSF2.1框架的一部分介绍到JPA,我现在面临一个奇怪的行为,我希望您能帮助我理解。 在我们的项目(使用NetBeans 7.2开发)中,我们有多个一对多关系,我们希望以与多对一导航相同的方式导航它们。事实上,只有在重启应用服务器(Glassfish 3.1.2)之后,我们才能让它们按照我们的意愿工作,而且,这种行为只会持续到下一次部署;这意味着我们每次应用修改时都需要重新启动Glassfish。。。 下面是一些代码摘录,帮助您了解我们的情况

这代表我们的主要实体(个人),其中包括与电子邮件和电话的一对多关系以及与AccountType的多对一关系

@Entity
public class Person implements Serializable {
    //
    //private non-collection fields including id 
    //

    @OneToMany(mappedBy="person", fetch=FetchType.EAGER)
    private Collection<Email> personEmails;

    @OneToMany(mappedBy="person")
    private Collection<Phone> personPhones;

    @ManyToOne
    private AccountType accountType;

    //
    // getter and setter, hashCode, isEqual and toString
    //
}
@Entity
public class AccounType implements Serializable {
    //
    //private non-collection fields including id 
    //

    private String name;

    @OneToMany(mappedBy="accountType")
    private Collection<Person> persons;

    //
    // getter and setter, hashCode, isEqual and toString
    //
}
。。。电话

@Entity
public class Phone implements Serializable {
    //
    //private non-collection fields including id 
    //

    private String number;

    @ManyToOne
    private Person person;

    //
    // getter and setter, hashCode, isEqual and toString
    //
}
。。。和帐户类型

@Entity
public class Person implements Serializable {
    //
    //private non-collection fields including id 
    //

    @OneToMany(mappedBy="person", fetch=FetchType.EAGER)
    private Collection<Email> personEmails;

    @OneToMany(mappedBy="person")
    private Collection<Phone> personPhones;

    @ManyToOne
    private AccountType accountType;

    //
    // getter and setter, hashCode, isEqual and toString
    //
}
@Entity
public class AccounType implements Serializable {
    //
    //private non-collection fields including id 
    //

    private String name;

    @OneToMany(mappedBy="accountType")
    private Collection<Person> persons;

    //
    // getter and setter, hashCode, isEqual and toString
    //
}
现在,只有在重新启动应用服务器后立即访问页面,我们才能得到预期的结果

forename    Alice
emails      2
phones      {[sums.groupa.entities.Phone[id=38]]}
accountType Student
如果在不可避免的部署之后修改任何内容(视图除外)并保存,结果会有所不同

forename    Alice
emails      0
phones      {[]}
accountType Student
为什么会发生这种情况?我们如何避免这种情况

提前谢谢

一些贡献者(我要感谢他们的快速回复)要求PersonFacade实现

public Person getFromUsername(String username)
    {
        try
        {
            Query q = em.createQuery("SELECT p FROM Person p LEFT JOIN FETCH p.personEmails WHERE UPPER(p.username) = :username");
            q.setParameter("username", username.toUpperCase());
            return (Person) q.getSingleResult();
        }
        catch (Exception ex)
        {
            Logger.getLogger(PersonFacade.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
正如您所看到的,我尝试按照建议使用FETCH JOIN,但查询得到的结果太多:它应该只获取一个代表Alice的Person实例,并在personEmails字段中包含两个电子邮件实例,但我怀疑它获取的是两个不同的Person实例,每个实例都附加了不同的电子邮件实例

原始查询如下:

SELECT p FROM Person p WHERE UPPER(p.username) = :username
再次感谢


AG

我不知道您是如何编写personFacade并获得Person实体的

但我猜你使用了查询


如果您正在使用JPQL,请尝试获取连接。

在“如果我们修改任何内容”后面隐藏了什么?您修改了什么以及如何修改?facade是如何得到这个人并将其返回的?我所说的“如果我们修改了任何东西”实际上是对托管bean、会话bean、实体bean或facade所做的每一次修改。这会导致NetBeans重新部署项目,并且由于某些原因,这会使急切获取类型“无效”。关于facade是如何实现的,我将编辑这篇文章。谢谢,需要JPQL吗?我会认为FetchType.Earge会排序吗?(尽管在这方面FetchType.LAZY应该是这样的。)JPQL不是必需的。我相信使用find()可以获得您想要的行为。我的意思是,如果您使用的是JPQL,请尝试fetch。我已经尝试了Tony Lang的建议,但它得到了太多的结果,前提是我在JPQL查询中正确使用了“fetch JOIN”。ThanksJPQL的fetch连接总是返回重复的结果,这是设计,而不是误用。请选择DISTINCT。非常感谢Tony,现在使用SELECT DISTINCT和JOIN FETCH,查询也可以正常工作,无需指定字段获取类型。
SELECT p FROM Person p WHERE UPPER(p.username) = :username