[英]Hibernate table relations with no foreign keys but shared field
我在需要關聯的幾個表上遇到問題。 這些表沒有外鍵,但是它們共享一個公共字段。 由於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),
那個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成員。
您的COST_CENTER_NUMBER被定義為VARCHAR,但是您的CostCenter類的ID為Int,因此您將獲得異常。
將ID類型更改為String,它應該可以工作。
該問題與缺少主鍵無關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.