2014-10-28 68 views
1

假设我们已实体A和实体B,各有其相应的表中,A和B.JPA /休眠如何从一个实体加入特定字段到一个不同的实体

实体A是旅馆,并且具有ID和几个字段,例如国家,城市,邮政编码等。

实体B是一个描述列表,它具有一个ID(与实体A中的ID相同)和另外两个字段Language和Description。

我做下面的查询在我的DAO:

Query query = getEntityManager().createQuery("FROM " + type.getSimpleName() + 
      " WHERE City = :cityParam AND Country = :countryParam"); 
    query.setParameter("cityParam", cityParam); 
    query.setParameter("countryParam", countryNameParam); 
    query.setMaxResults(numberOfResults); 
    List<HotelDto> hotelMap = query.getResultList(); 
    ListResponseModel result = new ListResponseModel(); 
    result.setHotelMap(hotelMap); 
    return result.getHotelMap().size() > 0 ? result : null; 

实体A,该酒店实体看起来是这样的:

@Entity 
@Table(name = "propertyList", uniqueConstraints = 
{ @UniqueConstraint(columnNames = "HotelID")}) 
public class Hotel implements Serializable, EntityWithId<Long> { 
private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue 
@Column(name = "HotelID") 
private Long hotelId; 

@Column(name = "Name") 
private String name; 

@Column(name = "Address") 
private String address; 

@Column(name = "City") 
private String city; 

@Column(name = "StateProvince") 
private String stateProvince; 

@Column(name = "PostalCode") 
private String postalCode; 

@Column(name = "Country") 
private String country; 

@OneToOne(fetch = FetchType.LAZY) 
@PrimaryKeyJoinColumn(name = "propertyhotelid") 
private PropertyDescription propertyDescription; 
[...] 

实体B的描述,是这样的:

@Entity 
@Table(name = "propertyDescriptionList", uniqueConstraints = 
{ @UniqueConstraint(columnNames = "HotelID")}) 
public class PropertyDescription implements Serializable, EntityWithId<Long> { 

private static final long serialVersionUID = 1L; 

@Id 
@Column(name = "HotelID", unique = true, nullable = false) 
private Long hotelId; 

@Column(name = "PropertyDescription") 
private String propertyDescription; 

问题是,一旦我得到结果集,一个实体将如下所示:

hotelId: 124125, 
name: "Random Hotel", 
address: "Some Address", 
city: "Shambala", 
postalCode: "W2 3NA", 
country: "Nevereverland", 
-propertyDescription: { 
    hotelId: 105496, 
    propertyDescription: "Insert Description here bla bla bla." 
} 
} 

我想是这样的:

hotelId: 124125, 
name: "Random Hotel", 
address: "Some Address", 
city: "Shambala", 
postalCode: "W2 3NA", 
country: "Nevereverland", 
propertyDescription: "Insert Description here bla bla bla." 
} 

因为我只是在说明本身它是一个字符串感兴趣,而不是具有同样的ID为整个对象(一个副本)。

什么是最好的方法来实现这一目标?

回答

3

从你的问题听起来像你正在寻找的是一种将两张表映射到一个实体的方法?如果是这样,你可以用@SecondaryTable来做到这一点:字符串'描述'然后将成为你酒店实体的一个字段。

@Entity 
@Table(name = "propertyList", uniqueConstraints = { @UniqueConstraint(columnNames = "HotelID") }) 
@SecondaryTable(name = "propertyDescriptionList", pkJoinColumns = @PrimaryKeyJoinColumn(name = "HotelID"), uniqueConstraints = { @UniqueConstraint(columnNames = "HotelID") }) 
public class Hotel implements Serializable { 

    @Id 
    @Column(name = "HotelID") 
    private Long hotelId; 

    @Column(name = "PropertyDescription", table = "propertyDescriptionList") 
    private String propertyDescription; 

} 
+0

是的,这正是我正在寻找的。谢谢 ! – 2014-10-29 14:20:54

0

您可以使用JPQL constructor expressions,并有这样的事情

"select new my.package.HotelDTO(h) from Hotel h where ..." 

而且你会需要一个场String propertyDescriptionHotelDTO

public HotelDTO(Hotel hotel) { 
    ... 
    this.propertyDescription = hotel.getPropertyDescription().getPropertyDescription(); 
    ... 
} 
0

构造为什么不把它作为一个延迟访场,而不是?

@Basic(fetch = FetchType.LAZY) 
private String propertyDescription; 

这样,除非特别要求,否则不会提取它,而是将它作为结果中的字符串字段获取。

+0

好吧,我该如何告诉jpa/hibernate从哪里获取该字段?另外,我如何具体要求提取?谢谢。 – 2014-10-28 14:02:30

+0

它将通过调用get方法自动获取(只要您处于活动会话中)。如果您想直接在查询中加载它们,请使用'SELECT FROM FROM A FROM FETCH ALL PROPERTIES WHERE ...'。 – Petter 2014-10-28 14:19:58