Hibernate Mapping思维错误
Hibernate Mapping thinking error
我有一个 2 数据库 table。首先有交易。每个交易都有一个 ID。这个ID也在我的第二个table中找到。第二个 table 包含费用,但我的第一个 table 没有关于费用的信息。现在我必须通过休眠映射获取与 1 笔交易相关的所有费用,但我不想在两个方向都有它。
贸易Class:
public class Trade {
@Id
@Column(name = "ID")
private Long tradeTag;
@ElementCollection
@CollectionTable(name = "VIE_CHARGES", joinColumns =
@JoinColumn(name="TRADE"))
private List<Charge> charges;
}
充电class:
public class Charge implements Serializable{
private static final long serialVersionUID = 1L;
@Id
private String chargeType;
@Id
@Column(name="TRADE")
private Long tradeTag;
}
负责 class,我不想持有任何有关交易的信息,但在交易 class 中有一份交易所有费用的清单。我很乐意在这里得到解决方案,因为我真的不知道该怎么做。
付费观看:
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: could not extract
ResultSet at
org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
at
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79)
at org.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)
at org.hibernate.loader.Loader.doQuery(Loader.java:932) at
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
at
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:319)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2327) at
org.hibernate.loader.collection.plan.LegacyBatchingCollectionInitializerBuilder$LegacyBatchingCollectionInitializer.initialize(LegacyBatchingCollectionInitializerBuilder.java:88)
at
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
at
org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
at
org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2150)
at
org.hibernate.collection.internal.AbstractPersistentCollection.doWork(AbstractPersistentCollection.java:567)
at
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249)
at
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:563)
at
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132)
at
org.hibernate.collection.internal.AbstractPersistentCollection.doWork(AbstractPersistentCollection.java:161)
at
org.hibernate.collection.internal.AbstractPersistentCollection.doWork(AbstractPersistentCollection.java:146)
at
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249)
at
org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145)
at
org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261)
at
com.mainfirst.emma.archive.trade.rims.TestDataBaseconnection.testTradeDao(TestDataBaseconnection.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at
java.lang.reflect.Method.invoke(Unknown Source) at
org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at
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(SpringJUnit4ClassRunner.java:252)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58) at
org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid
column name 'charges_TRADE'. at
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at
com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
at
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404)
at
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
at
com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at
com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
at
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
at
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285)
at
org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
at
org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
... 50 more
在hibernate 中,最好的方法是使用双向@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);
}
}
和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;
如果收费对象不需要自己的生命周期(没有自己的标识符,不被多个交易引用,不应该单独存在并且应该与它的交易一起删除),您可以将其映射为 @ElementCollection
值类型 (@Embeddable
).
映射的 table 和 id 列名可以通过 @CollectionTable
和 @JoinColumn
注释设置。它的默认值是 "trade_charges" 和 "trade_id".
@OrderColumn
注解只是一点点性能提升,只有当你面对集合的大量变化时才需要它。它将索引列添加到 trade_charges table 以标识更新/删除语句中的行。
例如交易:
@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;
}
所以在@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;
}
如果有人有更好的想法,请随时与我分享
我有一个 2 数据库 table。首先有交易。每个交易都有一个 ID。这个ID也在我的第二个table中找到。第二个 table 包含费用,但我的第一个 table 没有关于费用的信息。现在我必须通过休眠映射获取与 1 笔交易相关的所有费用,但我不想在两个方向都有它。
贸易Class:
public class Trade {
@Id
@Column(name = "ID")
private Long tradeTag;
@ElementCollection
@CollectionTable(name = "VIE_CHARGES", joinColumns =
@JoinColumn(name="TRADE"))
private List<Charge> charges;
}
充电class:
public class Charge implements Serializable{
private static final long serialVersionUID = 1L;
@Id
private String chargeType;
@Id
@Column(name="TRADE")
private Long tradeTag;
}
负责 class,我不想持有任何有关交易的信息,但在交易 class 中有一份交易所有费用的清单。我很乐意在这里得到解决方案,因为我真的不知道该怎么做。
付费观看:
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: could not extract ResultSet at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) at org.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) at org.hibernate.loader.Loader.doQuery(Loader.java:932) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:319) at org.hibernate.loader.Loader.loadCollection(Loader.java:2327) at org.hibernate.loader.collection.plan.LegacyBatchingCollectionInitializerBuilder$LegacyBatchingCollectionInitializer.initialize(LegacyBatchingCollectionInitializerBuilder.java:88) at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688) at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75) at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2150) at org.hibernate.collection.internal.AbstractPersistentCollection.doWork(AbstractPersistentCollection.java:567) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249) at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:563) at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132) at org.hibernate.collection.internal.AbstractPersistentCollection.doWork(AbstractPersistentCollection.java:161) at org.hibernate.collection.internal.AbstractPersistentCollection.doWork(AbstractPersistentCollection.java:146) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:249) at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:145) at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261) at com.mainfirst.emma.archive.trade.rims.TestDataBaseconnection.testTradeDao(TestDataBaseconnection.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at 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(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access[=14=]0(ParentRunner.java:58) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'charges_TRADE'. at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350) at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696) at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715) at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180) at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155) at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285) at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83) at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) ... 50 more
在hibernate 中,最好的方法是使用双向@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);
}
}
和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;
如果收费对象不需要自己的生命周期(没有自己的标识符,不被多个交易引用,不应该单独存在并且应该与它的交易一起删除),您可以将其映射为 @ElementCollection
值类型 (@Embeddable
).
映射的 table 和 id 列名可以通过 @CollectionTable
和 @JoinColumn
注释设置。它的默认值是 "trade_charges" 和 "trade_id".
@OrderColumn
注解只是一点点性能提升,只有当你面对集合的大量变化时才需要它。它将索引列添加到 trade_charges table 以标识更新/删除语句中的行。
例如交易:
@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;
}
所以在@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;
}
如果有人有更好的想法,请随时与我分享