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