【发布时间】:2018-10-21 17:32:48
【问题描述】:
我正在尝试在 JPA 中编程这种关系,但似乎在这里迷失了。
这是我的 ER 模型描述。
我有一个Customer,其中一个有一个Depot,而这个Depot 包含股份(股票)。
所以这就是我的想法。
每个Customer 都有一个Depot,即(有关系)1:1,一个仓库可以包含更多的股份(股票)。仓库 --> 共享 (1:m)
我有以下代码。
客户.java
@Entity
@NamedQuery(name = "Customer.getAll", query = "SELECT c FROM Customer c")
public class Customer implements Serializable {
private static final long serialVersionUID = 101L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id; //todo: for standard way of defining primary key
@NotNull
private String username;
@NotNull
private String firstName;
@NotNull
private String lastName;
@OneToOne
@JoinColumn(name="depot_id", nullable=false, updatable=false)
private Depot depot;
public Customer() {
super();
}
}
Depot.java
@Entity
public class Depot implements Serializable{
private static final long serialVersionUID = 102L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
/*@Column(name = "id", updatable = false, nullable = false)*/
@JoinColumn(name = "customer_id")
private Long id;
@OneToMany(mappedBy = "tdepot")
private List<Share> lshares;
//todo: Total estimated value in USD
@Transient
private BigDecimal totalValue = new BigDecimal(0.0);
public Depot(){
super();
}
@PostConstruct
public void init(){
if(lshares == null){
lshares = new ArrayList<>();
}
}
}
Shares.java
@Entity
public class Share implements Serializable{
private static final long serialVersionUID = 103L;
@Id
protected String symbol;
@NotNull
protected String companyName;
@NotNull
protected Long floatShares;
protected BigDecimal lastTradePrice;
@NotNull
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date lastTradeTime;
@NotNull
protected String stockExchange;
@ManyToOne(optional=false)
@JoinColumn(name="depot_id", nullable=false, updatable=false)
private Depot tdepot;
public Share(){
super();
lastTradeTime = new Date();
}
}
使用上面的代码,我什至可以创建并保留一个客户。我是不是做错了映射?
如果我尝试将数据持久保存到上述数据库中,我会收到以下错误消息。 [缩短可读性]
引起:javax.persistence.PersistenceException: org.hibernate.PersistentObjectException:分离的实体传递给 坚持:net.dsfinance.bank.ejb.entity.Customer
With .merge instead of persist
12:48:48,875 警告 [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (默认任务 46)SQL 错误:23502,SQLState:23502 12:48:48,876 错误 [org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务 46) “DEPOT_ID”列不允许为 NULL; SQL 语句:插入 客户(地址、depot_id、名字、姓氏、密码、角色、 用户名,id)值(?,?,?,?,?,?,?,?)[23502-173] 12:48:48,883 信息 [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (默认任务 46)HHH000010:在批次发布时,它仍然包含 JDBC 语句 12:48:48,888 WARN [com.arjuna.ats.arjuna](默认 任务 46) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - 失败 对于 SynchronizationImple
: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: 不能 执行语句 org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) 在 org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 在 org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) 在 org.hibernate.jpa.internal.EntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235) 在 org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2967) 在 org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339) 在 org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485) 在 org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.beforeCompletion(JtaTransactionCoordinatorImpl.java:316) 在 org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:47) 在 org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:37)
引起:org.hibernate.exception.ConstraintViolationException:可以 不执行语句 org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112) 在 org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207) 在 org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45) 在 org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2897) 在 org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3397) 在 org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89) 在 org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582) 在 org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456) 在 org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 在 org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 在 org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282) 在 org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465) 在 org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963) ... 129 更多 原因:org.h2.jdbc.JdbcSQLException: NULL not 允许列“DEPOT_ID”; SQL语句:
这是我在使用entitymanger.persist()的时候,谷歌搜索后,有人建议我应该使用merge,但仍然不允许我将客户添加到数据库中。
我想实现什么: 我想为一个简单的 tradeservice java EE 应用程序创建一个数据库, 拥有仓库的客户。包含购买特定客户的所有股票的仓库。 我如何实现这一目标?谢谢
【问题讨论】:
-
取决于你需要什么;你到底有什么问题?
-
@HBo 我的问题是如何正确链接实体之间的关系。这样我就可以将数据持久化到数据库中。截至目前我不能。在 Jboss Wildfly 服务器上运行它。
-
我在想 Depot 和 Customer 之间的关系是错误的,1:m 而不是 1:1。因为 Depot 表应该包含很多不同客户的 Depot 共享信息。
-
这就是背景很重要的地方(=您的需求)。例如,如果
depot不是很重要,您可以使用和@ElementCollection注释映射shares的集合(只是为了避免必须执行customer.getDepot().getShares()。为什么不能运行这个?什么例外,...? -
@HBo ElementCollection 听起来不错。只是为了切断漫长的道路。但我不知道该怎么做。您能否提供一个解决方案来简化此操作。客户和股份。谢谢。