I am trying to program this relationship in JPA but seems to be lost in here.
This is my ER-model decription.
I have a Customer
, which one have one Depot
and this Depot
contains shares(stocks).
So this is what I think.
Every Customer
has a Depot
that is (has relationship) 1:1 and a Depot can contain more Shares(stocks). Depot --> Shares (1:m)
I have the following code.
Customer.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();
}
}
With the above code I can even create and persist a Customer. Am I doing the mapping wrongly?
I am getting the following error message if I try to persist data into the above Database. [shorten for readibility]
Caused by: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: net.dsfinance.bank.ejb.entity.Customer
With .merge instead of persist
12:48:48,875 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-46) SQL Error: 23502, SQLState: 23502 12:48:48,876 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-46) NULL not allowed for column "DEPOT_ID"; SQL statement: insert into Customer (address, depot_id, firstName, lastName, password, role, username, id) values (?, ?, ?, ?, ?, ?, ?, ?) [23502-173] 12:48:48,883 INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (default task-46) HHH000010: On release of batch it still contained JDBC statements 12:48:48,888 WARN [com.arjuna.ats.arjuna] (default task-46) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffffc0a80869:-53b30100:5af571b4:4d, org.jboss.as.txn.service.internal.tsr.JCAOrderedLastSynchronizationList@6806a37a
: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) at org.hibernate.jpa.internal.EntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235) at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2967) at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485) at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.beforeCompletion(JtaTransactionCoordinatorImpl.java:316) at org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:47) at org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:37)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207) at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2897) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3397) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465) at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963) ... 129 more Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "DEPOT_ID"; SQL statement:
This was when i was using entitymanger.persist()
, after googling, some people suggested that I should use merge
but still didn't allow me to add customer into the database.
What do I want to achieve: I want to create a database for a simple tradingservice java EE application with, Customer having a Depot. Depot containing all the shares bought buy a specific Customer. How do I achieve this? Thanks