2017-04-18 112 views
0

我有2個數據庫表。首先進行交易。每筆交易都有一個ID。這個ID也可以在我的第二張表中找到。第二個表包含收費,但我的第一個表中有沒有關於費用的信息。現在我必須讓它們連接到1個交易由Hibernate映射的所有費用,但我不希望有這兩個方向。Hibernate映射思維錯誤

貿易類:

public class Trade { 
    @Id 
    @Column(name = "ID") 
    private Long tradeTag; 

    @ElementCollection 
    @CollectionTable(name = "VIE_CHARGES", joinColumns = 
    @JoinColumn(name="TRADE")) 
    private List<Charge> charges; 
} 

班主任:

public class Charge implements Serializable{ 

    private static final long serialVersionUID = 1L; 
    @Id 
    private String chargeType; 
    @Id 
    @Column(name="TRADE") 
    private Long tradeTag; 
} 

班主任,我不想保存有關交易的任何信息,但在貿易類的所有費用清單交易。我會很高興能在這裏得到一個解決方案,因爲我有真的不知道該怎麼做。

視圖負責人:

create view VIE_CHARGES as 
select CHRG_TYPE AS CHARGETYPE 
,TRAD_TAG AS TRADE 
from TRADE_CHARGE 

鑑於貿易:

create VIEW VIE_TRADE AS 
select TRAD_TAG as ID 
from TRADE 

錯誤是:

org.hibernate.exception.SQLGrammarException:無法在 提取 的ResultSet org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConvers ionDelegate.java:106) 在 org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) 在有機hibernate.loader.loader.getResultSet(Loader.java:2123)at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1911) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887 ) 在org.hibernate.loader.Loader.doQuery(Loader.java:932)在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) 在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(裝載機的.java:319) 在org.hibernate.loader.Loader.loadCollection(Loader.java:2327)在 org.hibernate.loader.collection.plan.LegacyBatchingCollectionInitializerBuilder $ LegacyBatchingCollectionInitializer.initialize(LegacyBatchingCollectionInitializerBuilder.java:88) 在 org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688) 在 org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitia lizeCollection(DefaultInitializeCollectionEventListener.java:75) 在 org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2150) 在 org.hibernate.collection.internal.AbstractPersistentCollection $ 4.doWork(AbstractPersistentCollection.java:567) 在 org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249) at org.hibernate.collection.internal.AbstractPersistentCollection。初始化(AbstractPersistentCollection.java:563) 在 org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132) 在 org.hibernate.collection.internal.AbstractPersistentCollection $ 1.doWork(AbstractPersistentCollection.java:161 ) 在 org.hibernate.collection.internal.AbstractPersistentCollection $ 1.doWork(AbstractPersistentCollection.java:146) 在 org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249) 在 org.hibernate作爲.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145) at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261) 在 com.mainfirst.emma.archive.trade.rims.TestDataBaseconnection.testTradeDao(TestDataBaseconnection.java:28) 在sun.reflect。 NativeMethodAccessorImpl.invoke0(本機方法)維持在 sun.reflect.DelegatingMethodAccessorImpl.invoke(來源不明) sun.reflect.NativeMethodAccessorImpl.invoke(來源不明)處 java.lang.reflect.Method.invoke(來源不明) org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在 org.jun it.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 在 org.springframework.test.context。 junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) 在 org.springframework.test.context。 junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4Class Runner.java:252) 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)在 org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access $ 000(ParentRunner。 Java的:58)在 org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluat E(RunAfterTestClassCallbacks.java:70) 在org.junit.runners.ParentRunner.run(ParentRunner.java:363)在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 在 org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 在 org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 在 org.eclipse.jdt.internal.junit.runner。RemoteTestRunner.run(RemoteTestRunner.java:382) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 引起:com.microsoft.sqlserver.jdbc.SQLServerException:無效的 列名'charges_trade'。在 com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) 在 com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515) 在 com.microsoft.sqlserver。 jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404) 在 com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement $ PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350) 在 com.microsoft.sqlserver.jdbc.TDSCommand.execute( IOBuffer.java:5696) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715) 在 com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180) 在 com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155) 在 com.microsoft.sqlserver。 jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285) 在 org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83) 在 org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement。 java:83) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) 。 .. 50更多

+0

使用@JoinColumn在貿易與參考充電 – rathna

+0

類的外鍵列類@ rathna是啊,但我不想收取任何有關交易的信息,如果可能的話(不要以爲這是) – XtremeBaumer

回答

1

如果充電對象並不需要一個自己的生命週期(沒有自己的標識,而不是由多個交易參考,不應該單獨存在,應該隨着交易而被刪除),您可以將其映射爲價值類型@ElementCollection@Embeddable)。

映射表和id列名稱可以由@CollectionTable@JoinColumn註釋設置。它的默認值是「trade_charges」和「trade_id」。

@OrderColumn註釋僅僅是一個小小的性能提升,只有在面對集合的很多更改時才需要它。它將一個索引列添加到trade_charges表中,以識別更新/刪除語句上的行。

例如貿易:

@Entity 
public class Trade { 

    @Id 
    @Column(name = "ID") 
    private Long tradeTag; 

    @ElementCollection 
    @CollectionTable(name = "charges", joinColumns = @JoinColumn(name="ID")) 
    @OrderColumn 
    private List<Charge> charges; 

} 

和充電:

@Embeddable 
public class Charge { 

    private String chargeType; 

} 
+0

與您的解決方案我得到一個無效的列名稱錯誤收費_Trade。任何想法如何我可以刪除名字中的'charges_'? – XtremeBaumer

+0

嗯。不應該有這樣的欄目。收費表應包含兩列,以charge ...開頭,這應該是charge_type和charges_order。哪個數據庫正在使用? –

+0

它是一個ms sql服務器。我用意見處理,因爲不應該以任何方式改變數據。因此我創建了一些視圖來映射類。如果我將列表名稱更改爲任何內容,錯誤中的列名將更改爲相同的值 – XtremeBaumer

1

在休眠期間,它是使用雙向@OneToMany並保持雙方關係同步的最佳方法。水木清華這樣的:

@Entity(name = "Person") 
public class Person { 

    @Id 
    @GeneratedValue 
    private Long id; 
    private String name; 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person") 
    private Set<Phone> phones=new HashSet<Phone>(); 
//getters and setters 
public void addPhone(Phone phone) { 
     phone.setPerson(this); 
     phones.add(phone); 
    } 

    public void removePhone(Phone phone) { 
     phone.setPerson(null); 
     phones.remove(phone); 
    } 
} 

和電話實體:

@Entity(name = "Phone") 
public class Phone { 

    @Id 
    @GeneratedValue 
    private Long id; 

    @Column(name = "`number`") 
    private String number; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "person_id", nullable = false) 
    private Person person; 

閱讀文檔https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-many

+0

這正是我不想做的 – XtremeBaumer

0
在文檔到@OneToMany有,我認爲它適合我的需要的例子儘可能

所以。

解決我與現在的工作:

public class Trade { 
    @Id 
    @Column(name = "ID") 
    private Long tradeTag; 
    @OneToMany(orphanRemoval=true) 
    @JoinColumn(name="trade") 
    private List<Charge> charges; 
} 

public class Charge implements Serializable{ 

    private static final long serialVersionUID = 1L; 
    @Id 
    private String chargeType; 
    @Id 
    @Column(name="TRADE") 
    private Long tradeTag; 
} 

如果有人有什麼更好的主意隨時與我分享