2017-04-18 111 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; 
} 

如果有人有什么更好的主意随时与我分享