1
我有以下几点:传递一个对象作为查询参数,并排除ID列
@Entity
@NamedQuery(name = "listCarsBySecurity", query = "SELECT c FROM Car c WHERE c.security = :security"
public class Car {
@Id
@GeneratedValue
private Long id;
@NotNull()
@Column(nullable = false)
private String make;
@NotNull()
@Column(nullable = false)
private String model;
// Some more fields
@NotNull()
@OneToOne (fetch = FetchType.LAZY, orphanRemoval=true)
private Security security = new Security();
// Some getters and setters
正如你可以看到,汽车类有一个“安全”的对象是LAZY牵强。安全类的样子:
@Entity 公共类安全{
@Id @GeneratedValue
private Long id;
// Security equipment. Add in alphanumerical order
private boolean abs;
private boolean airbag;
private boolean antispin;
// Some getters and setters
,你可以看到,命名查询列表尝试列出具有安全实体等于提供的安全对象的所有汽车。
持久的方法是这样的:
@Stateless
public class CarEJB {
@PersistenceContext(unitName = "carcmsPU")
private EntityManager em;
public List<Car> listCarsBySecurity(Security security) {
TypedQuery<Car> query = em.createNamedQuery("listCarsBySecurity", Car.class);
query.setParameter("security", security);
return query.getResultList();
}
和JUnit测试看起来像:
@Test
public void searchCar() throws Exception {
// Looks up the EJBs
carEJB = (CarEJB) ctx.lookup("java:global/classes/CarEJB");
// Create a new Ferrari with security = ABS brakes and Airbag
Car car = new Car();
car.setMake("Ferrari");
car.setModel("Some model");
car.setSubModel("Some sub model");
car.setEngine("Some engine");
car.setYear(1999);
car.getFuel().setGasoline(true);
car.setGearbox(Gearbox.AUTOMATIC);
car.setKilometres(323);
car.setDescription("This is a description");
Security security = new Security();
security.setAbs(true);
security.setAirbag(true);
car.setSecurity(security);
carEJB.createCar(car); // Persist
// Create a new security object and match it to the former one
Security securityObject = new Security();
securityObject.setAbs(true);
securityObject.setAirbag(true);
List<Car> carList = carEJB.listCarsBySecurity(securityObject);
assertTrue("Should contain at least 1 car with ABS and Airbag", carList.size() > 0);
for (Car carTemporary : carList) {
System.out.println(carTemporary.toString());
}
}
的事情是,在列表中不包含任何车都没有。我想我知道为什么;指定的查询会尝试将security_id与NULL匹配(因为我没有定义它)。
我的问题是:如何通过传递一个对象作为查询参数没有ID和通过不指定所有应在该对象内进行比较的字段来执行查询? (或如何从搜索中排除该ID)?
问候
您好,感谢为您的答案!我认为你的解决方案对我的应用程序来说很好,除了性能。前端是一个AJAX网页,并会执行很多查询。使用此解决方案是否会有很大的性能损失,例如安全类中的20个字段? – kungcc 2012-08-03 17:26:56
Criteria API最适合动态查询。如果您发现自己经常使用生成的查询,则可以考虑将其改为NamedQuery。就性能而言,标准可能会慢几毫秒,但最终,据我所知,没有任何意义上的差异。我已经添加了一些链接到我的答案与一些有趣的文章。 – Gamb 2012-08-03 19:04:58