【问题标题】:JPA/Hibernate how to join a particular field from an entity into a different entityJPA / Hibernate如何将实体中的特定字段连接到不同的实体中
【发布时间】:2014-10-28 13:33:42
【问题描述】:

假设我们有实体 A 和实体 B,每个实体都有对应的表 A 和 B。

实体 A 是一家酒店,具有 ID 和多个字段,例如 Country、City、PostalCode 等。

实体 B 是一个描述列表,有一个 ID(与实体 A 中的 ID 相同)和另外 2 个字段,语言和描述。

我正在我的 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(重复)的整个对象感兴趣。

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

【问题讨论】:

    标签: java database hibernate jpa persistence


    【解决方案1】:

    从您的问题看来,您正在寻找一种将两个表映射到一个实体的方法?如果是这样,您可以使用 @SecondaryTable 执行此操作:String 'description' 然后将简单地成为您的酒店实体的一个字段。

    @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;
    
    }
    

    【讨论】:

    • 是的,这正是我想要的。谢谢!
    【解决方案2】:

    你可以使用JPQL constructor expressions,有这样的东西

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

    您将需要一个字段String propertyDescriptionHotelDTO 中的构造函数

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

    【讨论】:

      【解决方案3】:

      为什么不把它作为一个懒惰的字段呢?

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

      除非特别要求,否则它不会被获取,并且您会在结果中将其作为字符串字段获取。

      【讨论】:

      • 好的,我如何告诉 jpa/hibernate 从哪里获取该字段?另外,我如何专门要求它被提取?谢谢。
      • 它将通过调用 get 方法自动获取(只要您处于活动会话中)。如果您想直接在查询中加载它们,请使用SELECT a FROM A a FETCH ALL PROPERTIES WHERE ...
      猜你喜欢
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2010-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多