【问题标题】:Hibernate Criteria restriction on a not loaded table未加载表的休眠条件限制
【发布时间】:2026-01-05 23:00:01
【问题描述】:

我正在尝试使用 Criteria 查询来限制未加载的实体。

我的映射都是通过一对多关系完成的。

例如,我正在尝试使用条件获取以下 SQL 查询:

SELECT {msg.*} FROM Messages AS msg  
WHERE msg.source_key IN 
  ( SELECT ds.unique_key FROM Data_Sources AS ds " +
    WHERE ds.source_type_key IN " +
       ( SELECT dst.unique_key FROM Data_Source_types AS dst " +
          WHERE unique_name = 'RequiredName' ) )

因此,我想获取消息,并在 Hibernate 未获取的实体上设置了限制。目前,我能得到的最好结果是:

Criteria crit = session.createCriteria( Message.class )
    .createAlias( "dataSource", "ds", CriteriaSpecification.INNER_JOIN )
    .createAlias( "ds.sourceType", "type" )
    .add( Restrictions.eq( "type.name", "HL7GatewayServer" ) )

但是,此查询还加载了 dataSource 和 dataSourceType。

编辑:我的映射:

消息:

@Entity
@Table(name="messages", schema="mySchema") 
@SequenceGenerator(name="sequence",sequenceName="mySchema.local_key_sequence")
public class Message
{
    @Id
    @Column(name = "unique_key")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
    private long                     id;

    @JoinColumn(name = "source_key")
    @ManyToOne(targetEntity = DataSource.class, fetch = FetchType.LAZY)
    private DataSource               dataSource       = null;
    [...]
}

数据源:

@Entity
@Proxy(lazy = true)
@Table(name = "data_sources", schema = "mySchema")
@SequenceGenerator(name = "sequence", sequenceName = "mySchema.local_key_sequence")
public class DataSource
{
    @Id
    @Column(name = "unique_key")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence")
    private long                      id;

    @JoinColumn(name = "source_type_key")
    @ManyToOne(targetEntity = DataSourceType.class, fetch = FetchType.LAZY)
    private DataSourceType            sourceType;

    @OneToMany(targetEntity = Message.class, mappedBy = "dataSource", fetch = FetchType.LAZY)
    private Set<Message>             messages = new HashSet<Message>();

    [...]
}

DATA_SOURCE_TYPE:

@Entity
@Table(name="data_source_types", schema="mySchema") 
@SequenceGenerator(name="sequence",sequenceName="mySchema.local_key_sequence")
public class DataSourceType
{
    @Id
    @Column(name="unique_key", unique=true,nullable=false)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence")
    private long id; 

    @OneToMany(targetEntity=DataSource.class, mappedBy="sourceType",fetch=FetchType.LAZY)
    private Set<DataSource> dataSources = new HashSet<DataSource>(0);

    [...]
}

我设法让它在 HQL 中工作,但是 有没有办法使用标准来实现这一点?

【问题讨论】:

  • 当你运行它时你会在休眠查询中得到什么。并显示您的映射。
  • 我所有的映射都是一对多的。当我运行它时,也会获取 DataSource 和 DataSourceType 对象,在这种情况下我想避免这种情况。

标签: sql hibernate select constraints


【解决方案1】:
try {

    crit = session.createCriteria(Message.class, "msg");
    crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    // UPDATE
    // Add your criteria sub query or any ...
}

并添加lazy='true'

【讨论】:

  • 但是Message.DataSource.DataSourceType.unique_name == 'RequiredName' 的限制将如何应用?
  • 不——它仍然会获取我不想获取的实体。 crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 只设置结果集的类型,但其他实体也会被获取并存储在缓存中。
  • @Ravi Parekh:添加了映射
  • @iliaden 你的意思是,标准也加载(SELECT * FROM Data_Sources AS ds) 而你不想加载它。我是吗?
  • 除了您的情况外,很可能不会加载所有标准。 :( 你也给我数据库表列表我会在我身边创建它然后测试。意思是在执行Criteria时看看,看看休眠查询给出了什么。