Hibernate表关系没有外键但是共享字段

时间:2015-04-09 17:10:39

标签: java hibernate jpa foreign-keys

我遇到了几个需要关联的表格的问题。这些表没有外键,但它们共享一个公共字段。由于ETL过程,我不允许操纵这些表。 我有两个实体:CostCenter和WellboreCompletion。它们共享一个名为costCenterNumber的字段。我想使用costCenterNumber进行查询,以便返回两个实体。

CostCenter.java

@Entity
@XmlRootElement

@Table(name = "DIM1_COST_CENTER", schema = "BIDW.dbo")
public class CostCenter implements Serializable {

@Id
@Column(name = "DK_COST_CENTER")
@GeneratedValue(generator="seq_item", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name="seq_item",sequenceName="DK_COST_CENTER", allocationSize=1)
@XmlAttribute
private Integer  id;


@Column(name = "COST_CENTER_NUMBER")
@XmlAttribute
private String costCenterNumber;


@OneToOne (mappedBy = "costCenterNumber", fetch = FetchType.EAGER)
@JoinColumn(name="COST_CENTER_NUMBER")
@XmlAttribute
private WellboreCompletion wellboreCompletion;

public String getCostCenterNumber() {
    return costCenterNumber;
}

public void setCostCenterNumber(String costCenterNumber) {
    this.costCenterNumber = costCenterNumber;
}

    public WellboreCompletion getWellboreCompletion() {
    return wellboreCompletion;
}

public void setWellboreCompletion(WellboreCompletion wellboreCompletion) {
    this.wellboreCompletion = wellboreCompletion;
}

//..more fields and more getters and setters

WellboreCompletion.java

@Entity
@XmlRootElement
@Table(name = "DIM1_WELLBORE_COMPLETION", schema = "BIDW.dbo")
public class WellboreCompletion implements Serializable{

@Id
@Column(name = "DK_WELLBORE_COMPLETION")
@GeneratedValue(generator="seq_item", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name="seq_item",sequenceName="DK_COMPLETION_NAME", allocationSize=1)
@XmlAttribute
private Integer  id;

@OneToOne(targetEntity = CostCenter.class)
@JoinColumn(name = "COST_CENTER_NUMBER",referencedColumnName = "COST_CENTER_NUMBER")
private String costCenterNumber;



public String getCostCenterNumber() {
    return costCenterNumber;
}

public void setCostCenterNumber(String costCenterNumber) {
    this.costCenterNumber = costCenterNumber;
}

.
.
//more fields with getters and setters

端点(REST):

 @GET
 @Path("/costcenter/{id}")
 public CostCenter getCostCenter(@PathParam("id") int id) {
    return wellSvc.getCostCenter(id);
 }

我服务中的方法:

@Override
public CostCenter getCostCenter(int id) {
    CostCenter cc = BIDWEntityManager.find(CostCenter.class, id);
    return  cc;
}

我知道这次搜索使用的是主键(ID)而不是costCenterNumber,但我认为这是第一步。

日志:

INFO  [stdout] (http-/0.0.0.0:8080-1) Hibernate: 
INFO  [stdout] (http-/0.0.0.0:8080-1)     select
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.DK_COST_CENTER as DK_COST_1_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.COMPANY_LONG_NAME as COMPANY_2_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.COST_CENTER_CATEGORY_LONG_NAME as COST_CEN3_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.COST_CENTER_LONG_NAME as COST_CEN4_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.COST_CENTER_NUMBER as COST_CEN5_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.COUNTRY_LONG_NAME as COUNTRY_6_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.DISTRICT_LONG_NAME as DISTRICT7_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.HIER_FIELD_LONG_NAME as HIER_FIE8_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.HIER_FIELD_CODE as HIER_FIE9_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.JOINT_VENTURE_CODE as JOINT_V10_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.JOINT_VENTURE_LONG_NAME as JOINT_V11_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.OPERATOR_LONG_NAME as OPERATO12_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.REGION_LONG_NAME as REGION_13_1_1_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.DK_WELLBORE_COMPLETION as DK_WELLB1_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.WB_API_NUMBER as WB_API_N2_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.TX_RRC_DISTRICT_ID as TX_RRC_D3_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.COMPLETION_DATE as COMPLETI4_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.COST_CENTER_NUMBER as COST_CE11_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.INITIAL_PRODUCTION_DATE as INITIAL_5_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.WB_SURVEY as WB_SURVE6_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.WB_GEOGRAPHIC_FOOTAGE as WB_GEOGR7_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.CLASS_LONG_NAME as CLASS_LO8_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.WELLBORE_NUMBER as WELLBORE9_4_0_,
INFO  [stdout] (http-/0.0.0.0:8080-1)         wellboreco1_.STATUS_LONG_NAME as STATUS_10_4_0_ 
INFO  [stdout] (http-/0.0.0.0:8080-1)     from
INFO  [stdout] (http-/0.0.0.0:8080-1)         BIDW.dbo.DIM1_COST_CENTER costcenter0_ 
INFO  [stdout] (http-/0.0.0.0:8080-1)     left outer join
INFO  [stdout] (http-/0.0.0.0:8080-1)         BIDW.dbo.DIM1_WELLBORE_COMPLETION wellboreco1_ 
INFO  [stdout] (http-/0.0.0.0:8080-1)             on costcenter0_.DK_COST_CENTER=wellboreco1_.COST_CENTER_NUMBER 
INFO  [stdout] (http-/0.0.0.0:8080-1)     where
INFO  [stdout] (http-/0.0.0.0:8080-1)         costcenter0_.DK_COST_CENTER=?

错误:

11:36:04,687 DEBUG [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-/0.0.0.0:8080-1) could not load an entity: [com.dvn.search.landFiles.detail.entity.CostCenter#44462] [select costcenter0_.DK_COST_CENTER as DK_COST_1_1_1_, costcenter0_.COMPANY_LONG_NAME as COMPANY_2_1_1_, costcenter0_.COST_CENTER_CATEGORY_LONG_NAME as COST_CEN3_1_1_, costcenter0_.COST_CENTER_LONG_NAME as COST_CEN4_1_1_, costcenter0_.COST_CENTER_NUMBER as COST_CEN5_1_1_, costcenter0_.COUNTRY_LONG_NAME as COUNTRY_6_1_1_, costcenter0_.DISTRICT_LONG_NAME as DISTRICT7_1_1_, costcenter0_.HIER_FIELD_LONG_NAME as HIER_FIE8_1_1_, costcenter0_.HIER_FIELD_CODE as HIER_FIE9_1_1_, costcenter0_.JOINT_VENTURE_CODE as JOINT_V10_1_1_, costcenter0_.JOINT_VENTURE_LONG_NAME as JOINT_V11_1_1_, costcenter0_.OPERATOR_LONG_NAME as OPERATO12_1_1_, costcenter0_.REGION_LONG_NAME as REGION_13_1_1_, wellboreco1_.DK_WELLBORE_COMPLETION as DK_WELLB1_4_0_, wellboreco1_.WB_API_NUMBER as WB_API_N2_4_0_, wellboreco1_.TX_RRC_DISTRICT_ID as TX_RRC_D3_4_0_, wellboreco1_.COMPLETION_DATE as COMPLETI4_4_0_, wellboreco1_.COST_CENTER_NUMBER as COST_CE11_4_0_, wellboreco1_.INITIAL_PRODUCTION_DATE as INITIAL_5_4_0_, wellboreco1_.WB_SURVEY as WB_SURVE6_4_0_, wellboreco1_.WB_GEOGRAPHIC_FOOTAGE as WB_GEOGR7_4_0_, wellboreco1_.CLASS_LONG_NAME as CLASS_LO8_4_0_, wellboreco1_.WELLBORE_NUMBER as WELLBORE9_4_0_, wellboreco1_.STATUS_LONG_NAME as STATUS_10_4_0_ from BIDW.dbo.DIM1_COST_CENTER costcenter0_ left outer join BIDW.dbo.DIM1_WELLBORE_COMPLETION wellboreco1_ on costcenter0_.DK_COST_CENTER=wellboreco1_.COST_CENTER_NUMBER where costcenter0_.DK_COST_CENTER=?]: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the varchar value 'N/A' to data type int.
.
.
WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-/0.0.0.0:8080-1) SQL Error: 245, SQLState: S0001
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-/0.0.0.0:8080-1) Conversion failed when converting the varchar value 'N/A' to data type int.
INFO  [org.hibernate.event.internal.DefaultLoadEventListener] (http-/0.0.0.0:8080-1) HHH000327: Error performing load command : org.hibernate.exception.SQLGrammarException: could not load an entity: [com.dvn.search.landFiles.detail.entity.CostCenter#44462]
DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] (http-/0.0.0.0:8080-1) Mark transaction for rollback
TRACE [org.hibernate.internal.SessionImpl] (http-/0.0.0.0:8080-1) Setting cache mode to: NORMAL
TRACE [org.hibernate.internal.SessionImpl] (http-/0.0.0.0:8080-1) Closing session
TRACE [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl] (http-/0.0.0.0:8080-1) Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@7f22462b]
TRACE [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] (http-/0.0.0.0:8080-1) Closing logical connection
TRACE [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] (http-/0.0.0.0:8080-1) Logical connection closed
TRACE [org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization] (http-/0.0.0.0:8080-1) JTA sync : afterCompletion(4)
TRACE [org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl] (http-/0.0.0.0:8080-1) Transaction afterCompletion callback [status=4]
TRACE [org.hibernate.ejb.AbstractEntityManagerImpl] (http-/0.0.0.0:8080-1) Session was closed; nothing to do
TRACE [org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl] (http-/0.0.0.0:8080-1) after transaction completion
DEBUG [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] (http-/0.0.0.0:8080-1) Aggressively releasing JDBC connection
TRACE [org.hibernate.internal.SessionImpl] (http-/0.0.0.0:8080-1) after transaction completion
ERROR [org.jboss.as.ejb3.invocation] (http-/0.0.0.0:8080-1) JBAS014134: EJB Invocation failed on component WellServiceImpl for method public abstract com.dvn.search.landFiles.detail.entity.CostCenter com.dvn.search.service.WellService.getCostCenter(int): javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not load an entity: [com.dvn.search.landFiles.detail.entity.CostCenter#44462]

根本原因似乎是:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the varchar value 'N/A' to data type int.

不知道为什么会发生这种转换,因为我没有int数据类型。 ' N / A'是我正在测试的情况下costCenterNumber的值,但它在实体中声明为String,表中声明为VARCHAR。

DDL:

DIM1_COST_CENTER:

COST_CENTER_NUMBER VARCHAR(30)

DIM1_WELLBORE_COMPLETION:

COST_CENTER_NUMBER VARCHAR(30),

2 个答案:

答案 0 :(得分:0)

sql join正在比较这两个值:

left outer join BIDW.dbo.DIM1_WELLBORE_COMPLETION wellboreco1_ 
 on costcenter0_.DK_COST_CENTER=wellboreco1_.COST_CENTER_NUMBER 

DK_COST_CENTER是CostCenter对象的Integer ID成员。 COST_CENTER_NUMBER是Wellbore对象的String成员。

答案 1 :(得分:0)

您的COST_CENTER_NUMBER定义为VARCHAR,但您的类CostCenter类的ID为Int,因此您将获得异常。

将ID类型更改为String,它应该可以工作。

问题与缺少主键无关。