在我们正在开发的这个应用程序中,我们注意到一个视图特别慢.我分析了视图并注意到hibernate执行了一个查询,即使数据库中只有两个对象要获取,也需要10秒.所有OneToMany和ManyToMany关系都是懒惰的,所以这不是问题.在检查正在执行的SQL时,我注意到查询中有超过80个连接.
进一步检查这个问题,我注意到问题是由实体类的深层次结构OneToOne和ManyToOne关系引起的.所以,我想,我只是让他们变得懒惰,这应该解决问题.但是,无论是标注@OneToOne(fetch=FetchType.LAZY)或@ManyToOne(fetch=FetchType.LAZY)似乎不工作.我得到一个异常,或者它们实际上并没有被代理对象替换,因此是懒惰的.
任何想法我将如何让这个工作?请注意,我不使用persistence.xml定义关系或配置细节,一切都在java代码中完成.
什么是CascadeType.REFRESH真正做?
它的定义是
刷新实体时,此字段中保留的所有实体也会刷新
但这在实践中意味着什么?有人可以给我一个简单的例子吗?
当我使用@Entity注释一个类并尝试解析依赖项时,我可以选择两个不同的包之间的包,javax.persistence.Entity和org.hibernate.annotations.Entity
javax包是JPA的实体注释,但为什么有一个hibernate实体注释,它与JPA的注释有什么区别?它只是一个允许定义更多属性的扩展吗?
理想情况下,在项目中,开发人员,测试人员,QA经理等都会对代码质量做出贡献.但是,如果你没有那种资源怎么办?例如,如果您只有三名开发人员并且没有资源聘请全职QA经理,您如何确保代码质量符合设定标准?
您在质量保证方面注意什么样的事情?质量不仅仅是代码执行它应该做的事情(代码通过自动测试正确测试).质量也与代码清晰(可读,可维护,结构良好,文档记录等)有关.
我期待听到您为团队应用了哪些流程,以确保质量符合既定标准.我们已经应用了一个流程,我们在开发人员之间轮换QA角色.每个开发人员一次负责一周的QA.修改每个变更集并检查现有测试是否通过,是否已编写新测试,代码是否干净,当然还有项目构建.
编辑:
当然,这个过程中的一些可以通过CI自动化,但我正在寻找的是人为因素的经验.我的意思是,你如何确保每个开发人员编写干净的代码并实际测试所有内容.除非您手动检查,否则测试覆盖范围不会告诉您是否所有内容都已经过测试(从自动角度来看,实际上不可能实现100%覆盖率).即使覆盖范围会告诉您某些内容已经过测试,但这并不意味着实际的测试会测试正确的内容.
这怎么可能,我必须遵循标准
Criteria criteria = getSession().createCriteria(c);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.add(Restrictions.eq("active",true));
List list = criteria.list();
列表的大小现在是20.如果我在条件中添加最大结果,
Criteria criteria = getSession().createCriteria(c);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setMaxResults(90);
criteria.add(Restrictions.eq("active",true));
List list = criteria.list();Run Code Online (Sandbox Code Playgroud)
..现在列表的大小是18!
在定义最大结果后,我不明白结果集大小如何更小,因为行数小于定义的最大值.这肯定看起来像一个bug,或者还有一些我不知道的hibernate奇怪的方面?
如果您正在寻找这个问题的答案,请务必阅读接受的答案及其评论.
是否可以从类中获取枚举值?让我详细说明一下.如果我有一个枚举例如FooBar,那么我可以通过调用FooBar.values()来获取FooBar的值,它将返回带有枚举的数组(FooBar []).我的问题是,我有一个方法,它将一个类(类c)作为输入参数,并在方法I中检查它是否是一个枚举(c.isEnum()).如果它是枚举,我需要以某种方式得到枚举值,问题是我不知道如何做到这一点,我甚至不完全确定它是可能的.那么,它是否可能,如果可能,我该如何实现这一目标?(注意,解决方案需要是通用的,换句话说,不是if-else的).
我有两个以下列方式注释的实体类
@Entity
class A {
@ManyToMany(mappedBy="A", cascade=CascadeType.ALL)
private List<B> b;
..
}
@Entity
class B {
@ManyToMany(cascade=CascadeType.ALL)
private List<A> a;
..
}
Run Code Online (Sandbox Code Playgroud)
如果我存储类'B'的实例,则关系存储在数据库中,类'A'中的getter将返回B的正确子集.但是,如果我更改"A"中的B列表,更改不会存储在数据库中?
我的问题是,我怎样才能使这两个类中的变化"级联"到另一个类?
编辑:我尝试了删除mappedBy参数和定义JoinTable(和列)的不同变体,但我一直无法找到正确的组合.
我有以下问题.我有三个类,A,B和C. A包含一个关于B:s的OneToMany关系列表.B包含与C的ManyToOne关系.C包含名为"name"的字段,B还包含名为"name"的字段.我想要完成的是让A列表中的项目主要按C的名称排序,其次按B的名称排序 - 问题是我不知道如何做到这一点.它甚至可能吗?
我正在使用EclipseLink作为我的JPA提供程序.
class A {
@OneToMany
@OrderBy("b.c.name, b.name") <---- this is the problem
List<B> b;
}
class B {
@ManyToOne
C c;
String name;
}
class C {
String name;
}
Run Code Online (Sandbox Code Playgroud)
编辑是的,我尝试了不同的变体,例如@OrderBy("c.name")不起作用,我只是收到一条错误消息,告诉我实体类b不包含名为"c.name"的字段.
我必须遵循实体对象
@Entity
public class Foobar {
...
private List<String> uuids;
...
}
现在我想制作一个条件查询来获取所有Foobar pojos,其uuids列表包含字符串"abc123",我只是不确定如何制定适当的标准.
我有一个名为AbstractEntity的类,它使用@MappedSuperclass注释.然后我有一个名为User(@Entity)的类,它扩展了AbstractEntity.这两个都存在于名为foo.bar.framework的包中.当我使用这两个类时,一切正常.但是现在我已经将包含这些文件的jar导入到另一个项目中.我想重用User类并使用一些额外的字段进行扩展.我认为这样@Entity public class User extends foo.bar.framework.User可以解决问题,但我发现User的这个实现只继承了AbstractEntity中的字段,但没有来自foo.bar.framework.User.问题是,如何让我的第二个User类继承第一个User实体类中的所有字段?
User类实现都有不同的表名,用@Table(name ="name")定义.
我的课程看起来像这样
package foo.bar.framework;
@MappedSuperclass
abstract public class AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
@Column(nullable = false)
@Version
protected Long consistencyVersion;
...
}
package foo.bar.framework;
@Entity
@Table(name = "foouser")
public class User extends AbstractEntity {
protected String username;
protected String password;
....
}
package some.application;
@Entity
@Table(name = "myappuser")
public class User extends foo.bar.framework.User {
protected String firstname;
protected String lastname;
protected String email;
....
}
使用上面的代码,EclipseLink将创建一个名为"myappuser"的表,其中包含字段"id","consistencyVersion","firstname","lastname"和"email".字段"username"和"password"不会创建到表中 - …
以下是我的应用程序的简化设置.它有一个Foobar类,它调用facade方法来获取数据.然后,外观调用Web服务来实际获取数据,然后稍微操作数据,然后将其返回到Foobar.
现在因为Web服务可能需要很长时间才能运行,所以对Facade的方法调用需要是异步的.因此,facade的方法没有返回值,而是使用回调对象.查看示例并继续阅读下面的内容.
public class Foobar {
private List<DTO> dtos;
@Autowired
private Facade facade;
public void refresh() {
facade.refreshFoobar(new CallBack() {
public void dataFetched(List<DTO> dtos) {
setDtos(dtos);
}
});
}
public void setDtos(List<DTO> dtos) {
this.dtos = dtos;
}
}
public class Facade {
...
public void refreshFoorbar(CallBack cb) {
// Fetch data from a web service
List<DTO> dtos = webService.getData();
// Manipulate DTOs
....
// call on the callback method
cb.dataFecthed(dtos);
}
}
Run Code Online (Sandbox Code Playgroud)
我有两种方法可以通过手动创建线程或使用spring @Async注释来使facade的方法异步.
public class Facade {
public …Run Code Online (Sandbox Code Playgroud) java ×10
jpa ×7
hibernate ×4
criteria ×2
criteria-api ×1
eclipselink ×1
enums ×1
junit ×1
qa ×1
testing ×1