2017-04-21 36 views
2

我有一个名为Trade的实体可以映射到包含属性的表。此实体也有一个字段,用于存储来自另一个表的值。我的Trade表包含第二个表的主键。我知道如何在整个Trade实体中将整个第二个表作为实体,但我只想要这1列。Hibernate从其他表中获取列的值

@Entity 
@Immutable 
@Table(name = "Trade table") 
@SecondaryTables(value = { 
    @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColumn(referencedColumnName = "id", foreignKey = @ForeignKey(name = "2ndtableID"))), 
    @SecondaryTable(name = "3rd table", pkJoinColumns = @PrimaryKeyJoinColumn(referencedColumnName = "id", foreignKey = @ForeignKey(name = "3rdtableID"))) }) 
public class TradeSearchResult { 
    @Id 
    @Column(name = "ID") 
    private Long primaryKey; 
    @Column(name = "col2", table = "2nd table") 
    private String valuefrom2ndtable; 
    @Column(name = "col3", table = "3rd table") 
    private String valuefrom3ndtable; 
} 

,你可以看到我试着用@SecondaryTables,但联接的样品从贸易实体的PrimaryKey执行。我如何使用注释从交易表中选择外键,将它加入到第二/第三表,并直接从col2/col3中直接得到值?任何建议表示赞赏

表贸易:

ID col1 fk1 fk2 
------------------------ 
1  abc 12  43  
2  def 23  32 
3  ghi 34  21 

表2:

ID col2 
---------- 
12 a 
23 b 
34 c 

表3:

ID col3 
----------- 
43 d 
32 e 
21 f 

现在我的贸易类应该具有的属性:

Long id; 
String col1; 
String col2; 
String col3; 

Hibernate查询:from Trade应该给我在这个例子中3个交易与属性:

Trade1: 1, "abc","a","d" 
Trade2: 2, "def","b","e" 
Trade3: 3, "ghi","c","f" 

,我不希望只创建一个实体,以达到属性col2col3

编辑:

select语句应该是这样的:

select trade.ID,TICKET,table2.col2,table3.col2 from trade join table 3 on table3.ID=trade.FKtable3 join table2 on table2.ID=trade.FKtable2 

如果我在sql server中执行这个语句,它会给我我想要的结果。我想映射我的类,以便hibernate生成此语句。

+0

名单我有类似的情况。你是否终于找到了一种方法来连接另一个表的值而不用声明一个描述另一个表的实体? – Cryptor

+0

@Cryptor我使用了'Criteria' API并且以这种方式映射它。 'valuefrom2ndtable'是通过查询内部的连接获取的。请注意,我的TradeSearchResult不是直接映射到任何表,但是我的Trade类仍然是。 – XtremeBaumer

回答

0

我解决此问题的是不是映射TradeSearchResult任何表和使用Criteria/CriteriaQuery API来获取我所需要的数据。我的Trade类完美映射到交易表并保存对其他表的对象的引用。现在到了查询是如何构建:

CriteriaBuilder cb = emf.getCriteriaBuilder(); 
CriteriaQuery<TradeSearchResult> query = cb.createQuery(TradeSearchResult.class); //type is the entity you want to map to 
Root<Trade> r = query.from(Trade.class); //root must be entity from which you can access all data 

List<Predicate> predicates = new ArrayList<Predicate>(); //new list of predicates 

predicates.add(cb.like(r.join("2ndTableEntityName").<String>get("valuefrom2ndtable"),"value to search for")); 
//get the needed value from 2nd table and map it to the field 

query.multiselect(r.get("2ndTableEntityName")).where(predicates.toArray(new Predicate[] {})); 
//create the query and execute it 
EntityManager em = emf.createEntityManager(); 
List<TradeSearchResult> results = em.createQuery(query).getResultList(); 
em.close(); 
return results; //return results 

此代码返回TradeSearchResult实体,只有需要的领域,而不是整个对象从其他类

0

根据javadoc example您应该使用pkJoinColumnforeignKey来定义女巫专栏应该用于加入您的表。

//编辑:

您的版本后,我试图使一些魔术:

@Entity 
@Immutable 
@Table(name = "\"Trade table\"") 
@SecondaryTables(value = { 
     @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColumn(name = "col2", referencedColumnName = "id")), 
     @SecondaryTable(name = "3rd table", pkJoinColumns = @PrimaryKeyJoinColumn(name = "col3", referencedColumnName = "id")) 
}) 
public class Trade { 

    @Id 
    @Column(name = "id") 
    private Long primaryKey; 

    @Column(name = "col2") 
    private String valuefrom2ndtable; 

    @Column(name = "col3") 
    private String valuefrom3ndtable; 


} 

@Entity 
@Table(name = "\"2nd table\"") 
public class Table2 { 

    @Id 
    private long id; 
} 

@Entity 
@Table(name = "\"3rd table\"") 
public class Table3 { 

    @Id 
    private long id; 
} 

我也得到SQL这样的:

create table "2nd table" (
    id bigint not null, 
    col2 bigint not null, 
    primary key (col2) 
); 

create table "3rd table" (
    id bigint not null, 
    col3 bigint not null, 
    primary key (col3) 
); 

create table "trade table" (
    id bigint not null, 
    col2 varchar(255), 
    col3 varchar(255), 
    primary key (id) 
); 

alter table "3rd table" 
    add constraint FK7tkn132p8joplte47ce169h82 
foreign key (col3) 
references "trade table"; 

alter table "2nd table" 
    add constraint FK9jsoykrvn4d0v4aor03g1l324 
foreign key (col2) 
references "trade table"; 

这看起来喜欢的事,你想要做,但我不是100%肯定...

+1

基于你的回答,我重写了我的代码,但它仍然在做同样的事情。我更新了我的代码以符合我现在的要求 – XtremeBaumer

+1

我不想为table2和table3创建类。我发布了一个应该由hibernate自动生成的select语句。不知何故,这必须是可能的... – XtremeBaumer

+0

我从休眠日志中得到这个SQL。 –

0

我不明白你为什么要那样做?如果您在Trade课程中有地图实体,则可以随时访问其属性,但我会尽力提供解决方案来回答您的问题。

那么你可以做到这一点,但你应该在两个实体之间使用OneToMany映射(所以你也应该存储整个映射的实体),并使用该表中的FK作为实体中的属性,并像这样映射它:

@JoinColumn(name="2ndtableID") 
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY) 
private Message message; 

@Column(name="2ndtableID") 
private Long secondTableID; 
+0

我不希望在我的交易实体中拥有整个第二/第三个实体作为属性。我只想要这些的一个属性。生病尝试使它在我的问题中更容易理解 – XtremeBaumer

+0

@XtremeBaumer恐怕不可能将这些实体作为持久字段来实现。 –

+0

我发布了应该从休眠执行的select查询。我认为这是可以告诉冬眠做到这一点 – XtremeBaumer

相关问题