在我的应用中,我有两个表,结算结果和结算状态结算结果包含一些基本数据,如名称、类型等。SettlementState是与结算结果关系的“多”面,由结算结果主键和状态组成,如主键和日期一样多对一的ID。示例数据:
Settlement Result
------------------------------
ID| Name | Sth
------------------------------
1 | Some Name | Something more
2 | Name2 | more2
Settlement State
----------
Result's ID | StatusId | Date
------------------------------
1 | 1 | some date
1 | 2 | date
1 | 3 | date
2 | 1 | date现在,我希望使用HQL/Plain SQL从结算结果中选择具有例如状态ID == 3的行,而不是具有更高Id的行。
有几种可能的状态:
Status ID | Desc
-----------------
1 | Created
2 | Confirmed
3 | Accepted
4 | Rejected当我们创建SettlementResult时,总会有一些“工作流程”。首先,Result的状态为Created (ID 1)。然后可以拒绝(ID 4)或确认(ID 2)。然后再一次,我们可以接受或拒绝。
因此,一个SettlementResult可以具有状态ID为1、2、4的SettlementStates (已创建、已确认,但不是Accepted=Rejected)。
问题是,我只想选择那些具有特定状态(对于examle Created)的SettlementResults。“
HQL查询如下:
Query query = session.createSQLQuery( "select distinct s from SettlementResult s join s.settlementStates states where states.settlementStatePK.status.statusId == 1" );返回所有结算结果,包括状态为1、2、3的结算结果(原因集合中包含ID为created的结算结果)。
可以只选择那些只具有特定状态的结算结果吗?例如,如果我们想要CreatedID 1,我们只会得到状态为1的所有结算结果,而没有2,3或4状态。当我们选择那些状态id为3的,我们可以接受,如果它有状态id = 1,2,3但不是4的结算状态。某种max[status.id]
@Entity
@Table(name = "SETTLEMENT_STATE")
public class SettlementState
{
@EmbeddedId
private SettlementStatePK settlementStatePK;
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "STATUS_DTTM")
private Date statusDate;
}
@Embeddable
public class SettlementStatePK implements Serializable
{
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "STATUS_ID")
private Status status;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SETTLEMENT_RESULT_ID")
private SettlementResult settlementResult;
}
@Entity
@Table(name = "SETTLEMENT_RESULT")
public class SettlementResult implements Serializable
{
@Id
@Column(name = "SETTLEMENT_RESULT_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "STATUS_ID")
private Status status;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MODEL_GROUP_ID")
private SettlementModelGroup settlementModelGroup;
@Column(name = "\"MODE\"")
private Integer mode;
@Column(name = "CREATED_DTTM")
private Date createdDate;
@Column(name = "DESCRIPTION")
private String description;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "settlementStatePK.settlementResult")
private List<SettlementState> settlementStates;
}发布于 2012-12-17 02:47:18
这里有两个选项:
如果您看到您的查询,那么您正在获取SettlementResult对象
Query query = session.createSQLQuery( "select distinct s from SettlementResult s join s.settlementStates states where states.settlementStatePK.status.statusId == 1" );你的查询是完美的,但是一旦你有了父对象SettlementResult并且你访问了OneToMany集合settlementStates,hibernate就会在SettlementResult P.K.的基础上加载所有它们(这也是你已经观察到的)。
所以-1\f25-1\f6选项-1\f25-1\f25:-1\f6从子-1\f6到-1\f25 Parent -1\f6这意味着从查询中返回SettlementState对象为:
Query query = session.createSQLQuery( "select distinct states from SettlementResult s join s.settlementStates states where states.settlementStatePK.status.statusId == 1" );然后,您可以从状态对象访问SettlementResult,因为您已经在SettlementState类中为SettlementResult定义了ManyToOne。在这种情况下,您肯定会拥有您正在寻找的那些SettlementResult对象。
选项-2: Divide your SettlementState objects选项1适合您,但是这个解决方案对您来说可能有点奇怪。因此,解决此问题的最好方法是您可以划分结算状态对象(如您的问题中所述)
1. RejectedSettlementState
2. NonRejectedSettlementState这两个类将扩展一个基础抽象类(SettlementState)。您可以在状态id上定义鉴别器公式。一旦拥有了这些类,就可以将这些子类关联到SettlementResult中。以下是您需要的类(sudo)
@DiscriminatorForumla("case when status_id == 4 then "REJECTEDSTATE" else "NONREJECTEDSTATE" end")
public abstract class SettlementState{
...
// Define all of your common fields in this parent class
}
@DiscriminatorValue("REJECTEDSTATE")
public class RejectedSettlementState extends SettlementState{
...
// define only fields specific to this rejected state
}
@DiscriminatorValue("NOTREJECTEDSTATE")
public class NonRejectedSettlementState extends SettlementState{
...
// define only fields specific to this non-rejected state
}现在,SettlementResult类
public class SettlementResult{
@OneToMany(fetch = FetchType.LAZY, mappedBy = "settlementStatePK.settlementResult")
private List<RejectedSettlementState> rejectedSettlementStates;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "settlementStatePK.settlementResult")
private List<NonRejectedSettlementState> nonRejectedSettlementStates;
}所以一旦你有了所有这些对象。这样就不需要查询状态了。您只需加载父对象SettlementResult,然后访问已拒绝或未被拒绝的结算状态。Hibernate将使用公式条件通过SettlementResult类中定义的延迟加载来初始化这些集合。
备注对我来说,这两种解决方案都是可以接受的,这取决于您希望在系统中使用哪种解决方案。第二种选择让你在未来有更多的优势。
任何更多信息:请询问!我已经尽了最大的努力让你理解这个想法:)。祝你好运!
https://stackoverflow.com/questions/13856898
复制相似问题