我正在尝试在我的新项目中使用Criteria API:
public List<Employee> findEmps(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
Root<Employee> emp = c.from(Employee.class);
c.select(emp);
c.distinct(emp);
List<Predicate> criteria = new ArrayList<Predicate>();
if (name != null) {
ParameterExpression<String> p = cb.parameter(String.class, "name");
criteria.add(cb.equal(emp.get("name"), p));
}
/* ... */
if (criteria.size() == 0) {
throw new RuntimeException("no criteria");
} else if (criteria.size() == 1) {
c.where(criteria.get(0));
} else {
c.where(cb.and(criteria.toArray(new Predicate[0])));
}
TypedQuery<Employee> q = em.createQuery(c);
if (name != null) {
q.setParameter("name", name);
}
/* ... */ …
Run Code Online (Sandbox Code Playgroud) 考虑以下JPQL查询:
SELECT foo FROM Foo foo
INNER JOIN FETCH foo.bar bar
WHERE bar.baz = :baz
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其转换为Critieria查询.这是我得到的:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> r = cq.from(Foo.class);
Fetch<Foo, Bar> fetch = r.fetch(Foo_.bar, JoinType.INNER);
Join<Foo, Bar> join = r.join(Foo_.bar, JoinType.INNER);
cq.where(cb.equal(join.get(Bar_.baz), value);
Run Code Online (Sandbox Code Playgroud)
这里显而易见的问题是我正在进行两次相同的连接,因为Fetch<Foo, Bar>
似乎没有方法来获取Path
.有没有办法避免必须加入两次?或者我是否必须坚持使用简单的查询这么好的旧JPQL?
这是我的JPA2/Hibernate定义:
Code:
@Column(nullable = false)
private boolean enabled;
Run Code Online (Sandbox Code Playgroud)
在MySql中,此列被解析为bit(1)数据类型 - 这对我不起作用.对于遗留问题,我需要将布尔值映射到tinyint而不是一点点.但我没有看到更改默认数据类型的可能性.有没有?
通常,我使用Hibernate的@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)来缓存@Entity类,它运行良好.
在JPA2中,还有另一个@Cacheable注释,它似乎与Hibernate的@Cache具有相同的功能.为了使我的实体类独立于hibernate的包,我想尝试一下.但我不能让它发挥作用.每次简单的id查询仍然会访问数据库.
谁能告诉我哪里出错了?谢谢.
实体类:
@Entity
//@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Cacheable(true)
public class User implements Serializable
{
// properties
}
Run Code Online (Sandbox Code Playgroud)
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:app.xml"})
@TransactionConfiguration(transactionManager="transactionManager")
public class UserCacheTest
{
@Inject protected UserDao userDao;
@Transactional
@Test
public void testGet1()
{
assertNotNull(userDao.get(2L));
}
@Transactional
@Test
public void testGet2()
{
assertNotNull(userDao.get(2L));
}
@Transactional
@Test
public void testGet3()
{
assertNotNull(userDao.get(2L));
}
}
Run Code Online (Sandbox Code Playgroud)
测试结果显示每个"get"命中DB层(使用hibernate.show_sql = true).
Persistence.xml:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_outer_join" value="true"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider"/>
<property …
Run Code Online (Sandbox Code Playgroud) 将JPA 2与EclipseLink实现一起使用.
我正在尝试构建一个动态查询,它应该会在给定日期之后保留一些记录.
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Event> criteria = builder.createQuery(Event.class);
Root<Event> root = criteria.from(Event.class);
criteria.select(root);
criteria.distinct(true);
List<Predicate> predicates = new ArrayList<Predicate>();
//...
if (dateLimit != null){
ParameterExpression<Date> param = builder.parameter(Date.class, "dateLimit");
predicates.add(builder.lessThanOrEqualTo(root.get("dateCreated"), param));
}
Run Code Online (Sandbox Code Playgroud)
lessThanOrEqualTo()
并且le()
是仅有的两个方法,在API中看起来像可以帮助我在这种情况下.这个警告是由日食引发的:
Bound mismatch: The generic method lessThanOrEqualTo(Expression<? extends Y>, Expression<? extends Y>)
of type CriteriaBuilder is not applicable for the arguments (Path<Object>, ParameterExpression<Date>).
The inferred type Object is not a valid substitute for the bounded parameter
<Y extends Comparable<? super Y>>
Run Code Online (Sandbox Code Playgroud)
我可以想象我没有采取正确的方法解决这个问题,但我无法找到任何可能解决方案的提示或指示.
我曾尝试多次使用子查询和IN
表达式编写查询语句.但我从来没有成功过.
我总是得到异常,"关键字'IN'附近的语法错误",查询语句是这样构建的,
SELECT t0.ID, t0.NAME
FROM EMPLOYEE t0
WHERE IN (SELECT ?
FROM PROJECT t2, EMPLOYEE t1
WHERE ((t2.NAME = ?) AND (t1.ID = t2.project)))
Run Code Online (Sandbox Code Playgroud)
我知道'IN'失败前的这个词.
你有没有写过这样的问题?有什么建议吗?
当我尝试使用JPA使用hibernate进行bean验证时,会发生以下异常:
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: Chapter11] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
at example.test.Test.main(Test.java:18)
Caused by: org.hibernate.HibernateException: Error applying BeanValidation relational constraints
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.applyRelationalConstraints(BeanValidationIntegrator.java:219)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:126)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:306)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1744)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
... 5 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.applyRelationalConstraints(BeanValidationIntegrator.java:208)
... 10 more
Caused by: java.lang.NoClassDefFoundError: javax/validation/ParameterNameProvider
at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:41)
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:269)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:111)
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:521)
at …
Run Code Online (Sandbox Code Playgroud) 是否可以使用JPA查询从对象中仅选择属性A和B而不使用条件查询?
要选择所有属性,我只需执行以下操作:
SELECT i FROM ObjectName i WHERE i.id = 10
Run Code Online (Sandbox Code Playgroud)
但是我在遗留系统上有一个具有许多属性的对象,并且想要选择几个,即使我知道选择几个属性通常很快.
这可能不使用标准查询吗?
谢谢!
我有一个注释的实体@Entity
.
如果我负责创建CREATE TABLE
脚本,为什么我应该指定@Column( nullable = false )
何时可以使用NOT NULL
关键字在数据库中创建列?是否有任何示例显示在字段中使用此属性的好处?
我与共享密钥有一对一的双向实体关系.当我尝试保存关联的所有者时,我得到了一个"null id generated"异常,对照关系的拥有方.我正在利用hibernate-entitymanager并使用spring进行事务管理.
拥有实体
@Entity
@Table(name = "lead")
public class Lead
{
private Long leadId;
private LeadAffiliate leadAffiliate;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getLeadId()
{
return leadId;
}
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public LeadAffiliate getLeadAffiliate()
{
return leadAffiliate;
}
}
Run Code Online (Sandbox Code Playgroud)
拥有实体
@Entity
@Table(name = "lead_affiliate")
public class LeadAffiliate
{
private Long leadId;
private Lead lead;
@Id
public Long getLeadId()
{
return leadId;
}
@MapsIdmappedBy = "leadAffiliate")
@OneToOne(cascade = CascadeType.All)
@PrimaryKeyJoinColumn
@JoinColumn(name = "lead_id")
public Lead getLead()
{
return lead; …
Run Code Online (Sandbox Code Playgroud)