我正在使用EJB和JPA,当我尝试访问PhoneNumber
phoneNumbers
属性中的Contact contact
个对象时,实际返回数据有时需要几分钟。它只返回没有phoneNumbers,甚至不返回null,然后,经过一段时间,当我再次调用它时,它会神奇地出现。
这是我访问数据的方式:
for (Contact c : contactFacade.findAll()) {
System.out.print(c.getName()+" "+c.getSurname()+" : ");
for (PhoneNumber pn : c.getPhoneNumbers()) {
System.out.print(pn.getNumber()+" ("+pn.getDescription()+"); ");
}
}
我正在使用netbeans生成的facade会话ejb(基本的CRUD方法)。 它始终打印正确的姓名和姓氏,只有经过一段时间(不一样)才能通过立面打印出来。我猜它与交易有关。怎么解决这个问题?
这些是我的JPA实体:
接触
@Entity public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String surname;
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "contact")
private Collection<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
PHONENUMBER
@Entity
public class PhoneNumber implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String number;
private String description;
@ManyToOne()
@JoinColumn(name="CONTACT_ID")
private Contact contact;
答案 0 :(得分:0)
您是否尝试过使用
fetch = FetchType.EAGER
您的OneToMany关系?
答案 1 :(得分:0)
检查生成的SQL,并尝试在数据库上查看它们所花费的时间...当他们直接在数据库中运行时! 如果你的SQL是针对一个调整不好的数据库运行的......没有什么可以帮助。
答案 2 :(得分:0)
鉴于您的实际映射,我认为您的代码实际上正在执行N + 1个请求(1个查询加载N Contact
,然后每个联系人1个查询以加载其PhoneNumber
)并依赖在Contact
的数量上,这可能变得非常低效。热切地加载关联可能是一个好主意(使用FETCH JOIN)。
激活生成的SQL的日志记录至少可以确认此行为并查看确切发生的情况。围绕循环添加一些日志语句也有助于查看花费的时间。如果某个地方的交易出现问题,它们也应该在日志中可见。
这实际上是我的主要观点:如果你想要改进某些东西,你需要先开始测量它。没有任何措施,你只是在黑暗中拍摄一些镜头。
如果无法衡量,则无法改善。 - Lord Kelvin