4
I have an N-N relationship that works as follows:
Destination.java (N)-(N) Customerservice.java
Within this relationship there is an entity that keeps the relationship Ids, which has some more values. The name of such is Serviceitem.java
Below the Entity’s:
Destination.java
@Entity
@Table(name="destination")
public class Destination implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_destination")
private Long idDestination;
@Column(name="tenant_id", insertable=false, updatable=false)
private Long tenantId;
@Column(name="appear_website")
private Boolean dtAppearWebsite;
@Lob
@Column(name="description")
@NotEmpty(message="O campo \"Descrição do Destino\" não pode estar em branco.")
private String dtDescription;
@OneToMany(mappedBy="destination")
private Set<ServiceItem> serviceItem;
//Mais campos adicionais e Getters and Setters
public Destination() {
}
}
Customerservice.java
@Entity
@Table(name = "customer_service")
public class CustomerService implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_customer_service")
private Long id;
@Column(name = "tenant_id", insertable = false, updatable = false)
private Long tenantId;
@Column(name = "date_service")
@DateTimeFormat(pattern = "dd/MM/yyyy")
@Temporal(TemporalType.DATE)
private Date date;
@Column(name = "average_budget")
private BigDecimal averageBudget;
@Column(name = "service_situation")
private boolean situation;
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "customerService")
private List<ServiceItem> serviceItem;
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "fk_history")
private History history;
@Column(name = "service_observatons")
private String serviceObservations;
public CustomerService() {
}
//Mais campos adicionais e Getters and Setters
}
Serviceitem.java
@Entity
@Table(name = "service_item")
@IdClass(ServiceItemId.class)
public class ServiceItem {
@Id
@ManyToOne
@JoinColumn(name="destination_id")
private Destination destination;
@Id
@ManyToOne
@JoinColumn(name="customerService_id")
private CustomerService customerService;
@Column(name="tenant_id", insertable=false, updatable=false)
private Long tenantId;
@Column(name="value_negotiated")
private double valueNegotiated;
@Enumerated(EnumType.STRING)
@Column(name="sale_type")
private SaleType saleType;
@Column(name="departure_date")
@DateTimeFormat(pattern="dd/MM/yyyy")
@Temporal(TemporalType.DATE)
private Date departureDate;
@Column(name="arrival_date")
@DateTimeFormat(pattern="dd/MM/yyyy")
@Temporal(TemporalType.DATE)
private Date arrivalDate;
@Column(name="requested_destination")
private Boolean requestedDestination;
@Column(name="negociation_observations")
private String negociationObservations;
public ServiceItem() {
}
//Getters and Setters
}
To generate id’s there is the class Serviceitemid.java
public class ServiceItemId implements Serializable {
private static final long serialVersionUID = 1L;
private Long destination;
private Long customerService;
public Long getCustomerService() {
return customerService;
}
public void setCustomerService(Long customerService) {
this.customerService = customerService;
}
public Long getDestination() {
return destination;
}
public void setDestination(Long destination) {
this.destination = destination;
}
@Override
public int hashCode() {
return (int) (destination + customerService);
}
@Override
public boolean equals(Object obj) {
if(obj instanceof ServiceItemId){
ServiceItemId serviceItemId = (ServiceItemId) obj;
return serviceItemId.destination == destination && serviceItemId.customerService == customerService;
}
return false;
}
}
Well, the question is when will I persist the data...
Dez 17, 2014 4:52:27 PM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [appServlet] in context with path [/viatge] threw exception [Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20131113-a7346c6): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'customerService_id' cannot be null
Error Code: 1048
Call: INSERT INTO service_item (arrival_date, departure_date, negociation_observations, requested_destination, sale_type, value_negotiated, customerService_id, destination_id, tenant_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
bind => [2016-08-01, 2015-10-01, teste, true, SUBMITTED_BUDGET, 3658.98, null, 1, 2]
Query: InsertObjectQuery(br.com.joocebox.model.ServiceItem@6e92b1b1)] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'customerService_id' cannot be null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
I even understand that it is missing inform the id customerService_id in the Serviceitem.java entity, but this id will be generated automatically, as it is incorrect for me to enter the id in hand.
How could I proceed in such a case?
EDITION
Come on!
My Entity Customerservice (which refers to a service) has many destinations (in this case Destination), as many destinations may belong to many Customerservice.java (support).
Note that there is no relationship @Manytomany directly between the entities, but there is a class called Serviceitem that makes the union between the two entities.
When I will persist a Serviceitem, my id related to Destination is loaded, (because it already exists), already the Customerservice has not been persisted, so it will not have an ID which is the cause of the problem.
Why is it incorrect to inform the ID "at hand"? Where was this information taken from? You can very well use a method with @Prepersist and assign a UUID to your key for example. This is what I usually use, even more in distributed systems, is the fastest solution I see to avoid bottleneck with sequential id generation in concurrent environment. I’m not sure I understand your application (specify better if my answer is vacant). From a business point of view, it is necessary to have a composite primary key ? why not just use a specific field for the ID ?
– Josh
Well, @Josuéeduardo, in my understanding it would not be a "good practice" to inform the id’s, but it seems I’m wrong. Well I’m performing the mapping between the entities so Many-to-Many with additional fields. The form of which it was made was the same found in this link: http://uaihebert.com/jpa-mini-bookletFirst Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step Step because my idea was that customerService_id would be generated automatically. Grateful for the clarification
– João Manolo
Just one more detail: unfortunately Serviceitemid.hashcode() has been implemented incorrectly, 1+2=3 and 2+1=3, I advise you to take a look here: http://stackoverflow.com/questions/10034328/hashcode-for-objects-with-only-integers... Regarding the question in question: Are you sure that the two entities that make up the primary key are not null ? If you have any more details about the status of Destination and Customerservice I think it would help us a little better. What I think is that Serviceitem was not instantiated.
– Josh
I won’t be long because I’m on a cell phone. But I’ll be direct. 1- When 1 saw N-N in the title, I imagined the association MANY to MANY (I went to look up the @Manytomany annotation and couldn’t find it); 2- I find this mapping mode very confusing, if you have composite keys, why don’t you use Embeddable ? ; 3- Avoid using Prepersist to the fullest, if an id is required to be generated, make this explicit in your software’s business layer; 4- as mentioned above, correctly implement the hashcode.
– wryel
Thank you for observing the poor implementation of hashcode(), I will fix it. So they are not null. The problem occurs with the Customerservice id, as it has not yet persisted in the database, so the integrity problem occurs. The serviceItem cannot perform the Insert precisely for the reason that the Customerservice id is missing. The question is whether there is a way to generate such an id automatically. or I should record a Customerservice first and then record a Serviceitem?
– João Manolo
@wryel, such an example has been picked up in books and websites, as I am using the N-N approach with additional fields (http://uaihebert.com/jpa-mini-booklet-first passos-passos-e-concettes/22/). So far I only know this approach.
– João Manolo
Then do so please edit your question and there at the end put the scenario you are trying to accomplish, e.g.: 1 person has N Children, 1 Son has N carts. Make it clearer to us that we’re trying to help. (Taking advantage, the problem with this Idclass note is that it marries more legacy systems than new systems, in which Embeddable makes much more sense [in fact you make a class that takes on the identity of an entity])
– wryel
@wryel, I did the editing well mitigating the situation, as I changed the question (I hope you are legal).
– João Manolo
@Josuéeduardo, I was reading about the implementation of a UUID for id (performing a @Prepersist) and I thought it would solve my problem perfectly. To be honest I did not know this form of generation of id’s. Could you illustrate me an example and comment (if not too laborious) what are the advantages and disadvantages of such an approach? Grateful!
– João Manolo