JPA Collection mapping to Master table - jpa

I have a number of ServiceDefinition entities. I'm trying to create a series of License entities that contain a reference to one or more ServiceDefinition entities;
#Entity
public class License {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(unique=true, nullable=false)
private int id;
#Column(name="serial")
private int serialNumber;
#OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
protected List<ServiceDefinition> definitions;
<-- rest of class omitted -->
#Entity
public class ServiceDefinition implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(unique=true, nullable=false)
private int id;
<-- rest of class omitted -->
When the database is instantiated JPA creates me a ServiceDefinition table, a License table and a License_ServiceDefinition table.
I have been able to add and update records into this structure, but when I try to delete a License enity, JPA deletes the entries from the License_ServiceDefinition table and the License table. Then JPA tries to delete from the ServiceDefinition table which I don't want.
The ServiceDefinition is a "Master" table and in the same way as an OrderHeader entity might contain a reference to a Customer entity and deleting the OrderHeader should not result in deletion of the Customer, I want to be able to delete a License and it's references to ServiceDefinition entities without deleting the ServiceDefinition itself. I hope that makes sense.
Is this possible or do I need to deal with this manually.
Regards
Regards

Just remove the cascade=CascadeType.ALL and orphanRemoval=true from the annotation.
orphanRemoval=true means that if a service definition is removed from the list of service definitions, it should be removed.
CascadeType.ALL means that every operation made on a license should be cascaded to each service definition in the list. So if you delete the license, the service definitions in the list are deleted in cascade.
Those attibutes have a meaning, and have consequences. Don't use them without understanding their meaning. And don't add them everywhere thinking you code might magically work better.

Related

Spring Boot H2 create log table with many-to-many relationship to other table

Let's say I have a table Account, which contains info about clients accounts. I want to create a log table (containing sender and recipient fields), and every time when a request is sent to server (e.g. there was a transfer between two accounts) I want to insert info about this operation to this table.
So I supose I need to create many-to-many relationship between Account and Log table. But what joins do I need then? The sender and recipient fields in Log table have to be objects of Account class. How can I map them with Spring JPA annotations?
You can create the follow code to solve your problem.
Firstly, you must define the Account class in this way:
#Entity
public class Account{
#GeneratedValue
#Id
private long id;
//others fields bellow
}
and then you can create a new Log class who it has two field with the recipient and sender and both has #ManyToOne relationship like this:
#Entity
public class LogAccountTransference{
#GenerateValue
#Id
private long id;
#ManyToOne
private Account recipient;
#ManyToOne
private Account sender;
//others field about Log Table
}
If you still will have some question just tell me.

jpa repository save method returns different id from the one inserted into database

I'm using spring data (jpaRepository) + Oracle 11g Database.
Here's the code of my JUnit test:
#Test
public void testAjoutUtilisateur() {
Utilisateur utilisateur = new Utilisateur();
(...)
utilisateur=repository.save(utilisateur);
Utilisateur dbutilisateur = repository.findOne(utilisateur.getIdutilisateur());
assertNotNull(dbutilisateur);
When I debug I find that "utilisateur" object returned by repository.save method has an id like "2100" while the corresponding inserted line in the database have an id like "43".
I have an Oracle database with a sequence and a trigger to have the auto incremented property for the id for my "Utilisateur" table.
Here is the id definition in my Utilisateur entity:
#Entity
#NamedQuery(name="Utilisateur.findAll", query="SELECT u FROM Utilisateur u")
#SequenceGenerator(sequenceName="ID_UTILISATEUR_SEQ", name="ID_UTILISATEUR_SEQ")
public class Utilisateur implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ID_UTILISATEUR_SEQ")
private Long idutilisateur;
Where is the problem? Is it within the save method?
Thank you.
Edit:
I figured out that the problem was already solved by the solution of #jhadesdev and the data lines I was talking about were inserted when the triggers were actives.
Finally, I have to mention that by default the JUnit test seems to not insert data in the database (it inserts then rollback). In order to invalidate this behaviour we have to specify the #TransactionConfiguration(defaultRollback=false) annotation in the test class.
For example (in my case):
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:context/dao-context.xml" })
#TransactionConfiguration(defaultRollback=false)
#Transactional
public class UtilisateurRepositoryTest {
Hope it can help someone.
The problem is that two separate mechanisms are in place to generate the key:
one at Hibernate level which is to call a sequence and use the value to populate an Id column and send it to the database as the insert key
and another mechanism at the database that Hibernate does not know about: the column is incremented via a trigger.
Hibernate thinks that the insert was made with the value of the sequence, but in the database something else occurred. The simplest solution would probably be to remove the trigger mechanism, and let Hibernate populate the key based on the sequence only.

JPA Simple ForeignKey relationship

Is it possible to create a basic FK relationship in JPA without involving the full entity target object?
As an example, imagine I have an entity:
#Entity(name = "Mechanic")
public class Mechanic {
#Id
private Long id;
//...
and a Car that I want to reference a Mechanic.id:
#Entity(name = "Car")
public class Car {
//...
#NotNull
private Long mechanic_id;
From an Object perspective, this would be a unidirectional, one to one relationship with the Car requiring a Mechanic.id and the Mechanic not needing any back reference to Car.
All I want out of this is to store the Mechanic.id ONLY. For the purposes of this question it is not useful to have a #OneToOne (or #OneToMany etc) relationship with the entity reference, I'm explicitly trying to avoid that but still retain the underlying integrity that a FK will provide.
JPA 2 and I'm using EclipseLink.

JPA #EmbeddedId: How to update part of a composite primary key?

I have a many-to-many relationship where the link table has an additional property. Hence the link table is represented by an entity class too and called Composition. The primary key of Composition is an #Embeddable linking to the according entities, eg. 2 #ManyToOne references.
It can happen that a user makes an error when selecting either of the 2 references and hence the composite primary key must be updated. However due to how JPA (hibernate) works this will of course always create a new row (insert) instead of an update and the old Composition will still exist. The end result being that a new row was added instead of one being updated.
Option 1:
The old Composition could just be deleted before the new one is inserted but that would require that the according method handling this requires both the old and new version. plus since the updated version is actually a new entity optimistic locking will not work and hence last update will always win.
Option 2:
Native query. The query also increments version column and includes version in WHERE clause. Throw OptimisticLockException if update count is 0 (concurrent modification or deletion)
What is the better choice? What is the "common approach" to this issue?
Why not just change the primary key of Composition to be a UID which is auto-generated? Then the users could change the two references to the entities being joined without having to delete/re-create the Composition entity. Optimistic locking would then be maintained.
EDIT: For example:
#Entity
#Table(name = "COMPOSITION")
public class Composition {
#Id
#Column(name = "ID")
private Long id; // Auto-generate using preferred method
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn( .... as appropriate .... )
private FirstEntity firstEntity;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn( .... as appropriate .... )
private SecondEntity secondEntity;
....

JPA Composite Primary Key generating

I have simple entity class (irrelevant methods omitted):
#Entity
#Table(name="CONNECTIONS")
public class Connection implements Serializable {
#Id private Long id_track;
#Id private Long id_carrier;
#Id private Date date_out;
#Id private Time time_out;
private Date date_in;
private Time time_in;
private Double price;
...
}
I expect that JPA (in my case Eclipse implementation) creates TABLE CONNETIONS with composite primary key that consists of id_track, id_carrier, date_out and time_out columns but it adds addidional column id (of type integer) What do I do wrong?
I can not reproduce this. Are you sure JPA is creating your table?
Also ensure you have recompiled and redeployed your code.
Perhaps enable logging, and include what JPA provider and version you are using.
Are you using Glassfish?