Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate从其他表获取列的值_Java_Hibernate_Hibernate Mapping - Fatal编程技术网

Java Hibernate从其他表获取列的值

Java Hibernate从其他表获取列的值,java,hibernate,hibernate-mapping,Java,Hibernate,Hibernate Mapping,我有一个名为Trade的实体,它可以映射到包含属性的表。该实体还有一个字段,用于存储另一个表中的值。我的交易表包含第二个表的主键。我知道如何将整个第二个表作为我的交易实体中的实体,但我只想要那1列 @Entity @Immutable @Table(name = "Trade table") @SecondaryTables(value = { @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColum

我有一个名为Trade的实体,它可以映射到包含属性的表。该实体还有一个字段,用于存储另一个表中的值。我的交易表包含第二个表的主键。我知道如何将整个第二个表作为我的交易实体中的实体,但我只想要那1列

@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上执行的。如何使用注释从trade表中选择外键,将其连接到第二个/第三个表,并直接从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;
Trade1: 1, "abc","a","d"
Trade2: 2, "def","b","e"
Trade3: 3, "ghi","c","f"
hibernate查询:
from Trade
在本例中应为我提供3个具有以下属性的交易:

Long id;
String col1;
String col2;
String col3;
Trade1: 1, "abc","a","d"
Trade2: 2, "def","b","e"
Trade3: 3, "ghi","c","f"
我不想创建一个实体仅仅是为了访问属性
col2
col3

编辑:

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
@JoinColumn(name="2ndtableID")
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY)
private Message message; 

@Column(name="2ndtableID")
private Long secondTableID;
如果我在sql server中执行此语句,它将给出我想要的结果。我想映射我的类,以便hibernate生成此语句。

基于此,您应该使用
pkJoinColumn
foreignKey
来定义应该使用哪些列来连接表

//编辑:

在您的版本之后,我尝试制作一些魔术:

@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%确定…

我不明白你为什么要这么做?如果您的
Trade
类中有映射实体,您可以随时访问其属性,但我将尝试提供一个解决方案来回答您的问题

您可以这样做,但是您应该在两个实体之间使用
OneToMany
映射(因此您也应该存储整个映射的实体),并将此表中的FK用作实体中的属性,并将其映射为:

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
@JoinColumn(name="2ndtableID")
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY)
private Message message; 

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

我解决这个问题的方法是不将
TradeSearchResult
映射到任何表,并使用
CriteriaQuery
/
CriteriaQuery
API获取我需要的数据。我的
Trade
类完全映射到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
CriteriaBuilder cb=emf.getCriteriaBuilder();
CriteriaQuery=cb.createQuery(TradeSearchResult.class)//类型是要映射到的实体
Root r=query.from(Trade.class)//根目录必须是可以从中访问所有数据的实体
列表谓词=新的ArrayList()//新谓词列表
add(cb.like(r.join(“2ndTableEntityName”).get(“valuefrom2ndtable”),“要搜索的值”);
//从第二个表中获取所需的值,并将其映射到字段
multiselect(r.get(“2ndTableEntityName”)).where(predicates.toArray(new Predicate[]{}));
//创建查询并执行它
EntityManager em=emf.createEntityManager();
List results=em.createQuery(query.getResultList();
em.close();
返回结果//返回结果

此代码返回一个
TradeSearchResult
实体列表,其中仅包含所需字段,而不包含其他类的全部对象

根据您的回答,我重新编写了代码,但它仍在执行相同的操作。我更新了有问题的代码以匹配我现在的代码,我不想为表2和表3创建类。我发布了一条select语句,它应该由hibernate自动生成。不知何故,这必须是可能的…我从hibernate日志中得到了这个SQL。我不想在我的交易实体中有整个第二/第三实体作为属性。我只想要其中的一个属性。我会尽量用我的语言使它更容易理解question@XtremeBaumer如果没有这些实体作为持久字段,恐怕不可能做到这一点。我发布了select查询,该查询应该从hibernate执行。我认为告诉hibernate这样做是可能的,因为表之间的
连接
,它肯定会工作。您的实际Hibernate配置是否生成此查询?!我对此表示怀疑。不,它不是。。。但这是一个应该产生的我有类似的情况。您是否最终找到了一种方法来连接另一个表中的值,而不声明描述另一个表的实体?@Cryptor我使用
Criteria
API并以这种方式映射它
valuefrom2ndtable
是通过查询中的联接获取的。请注意,我的
TradeSearchResult
没有直接映射到任何表,但我的
Trade
类仍然是。