Reputation: 21
I'll briefly explain the situation. I have 2 entities, one is the owner and has the FKs while the other is the joined entity. The situation is that the owner can have only one non-owner associated while the non-owner can have many owners. However, I think that what I need is a unidirectional OneToOne since I want to be able to do all CRUD operations in the owner side but I don't want any of the non-owners to be updated or deleted due to the operations I'm doing to the owner. Please do correct me if this reasoning is wrong. So this is what I have:
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Column
private fk_id;
// various fields with their getter and setters
@OneToOne
@JoinColumn(name = "fk_id", referencedColumnName = "id", insertable = false, updatable = false)
private Child childEntity;
}
@Entity
public class Child{
@Id
@Column(name = "id", updatable = false, nullable = false)
private Long id;
}
The problems I'm having are the following: - Trying to insert new Owners with a valid fk_id results in ids for this class must be manually assigned before calling save() error I tried fixing this but soon realized that this isn't actually the problem. I'm having this problem because when creating a new Owner JPA is actually trying to create a child linked to this parent and it can't do so because I have no generation strategy for the ID (which is what I want).
After various tries I feel that this is the problem, I can't add a new parent that's linked to an already existing child since for every parent I try to add JPA tries to add a corresponding new child.
I thought I would fix this with the unidirectional OneToOne relationship but either I'm doing it wrong or something else is wrong since the unidirectional OneToOne requires me a cascade type which I don't want.
EDIT: I'm trying to insert a new owner, which is linked to a non-owner like this:
public Long insertAccount(Owner record) {
insert(record);
return record.getId();
}
public Long insert(T entity) {
entityManager.persist(entity);
return entity.getId();
}
The insertable = false, updatable = false appears to be necessary since the fk_id is also a column of the class.
EDIT 2: By having in the owner the following:
@ManyToOne
@JoinColumn(name = "fk_id", insertable = false, updatable = false)
private Child childEntity;
I get the following error:
object references an unsaved transient instance - save the transient instance before flushing
is there any way to fix it without adding the cascade option? As I mentioned above, when inserting a new owner I don't want to change the non-owner side at all.
Another example I thought of is the following: Owner = students which have a reference to the university Non-owner = university.
Student class has @ManyToOne annotation, university class doesn't have any annotations. I want it to be unidirectional, I want to add a new student which will have a reference to a university but I don't want to add another university with that student.
This is what it would appear that JPA is trying to do
Upvotes: 1
Views: 2368
Reputation: 1292
The (Father -> Child) relationship is ManyToOne
I don't understand the problem very well, if the child entity already exists, you will have to obtain the complete object of BBDD so that it is not a transient entity and establish it as the parent property.
In addition, remove insertable false and updatable false, it is implicit:
@JoinColumn (name = "fk_id", referencedColumnName = "id", insertable = false, updatable = false)
If you wanted to set it to true you would have to set the type of relationship, the type of deletion, update ... etc
@ManyToOne (cascade = {CascadeType.MERGE, CascadeType.PERSIST})
Could you put the piece of code in which you persist the new father?
EDIT 2:
The transient error is why you are trying to insert a parent entity. It contains a child entity that you want to relate to that is not exactly the same as the database entry. The child entity exist in DDBB? if the response is yes you have the id of child entity try this:
public Long insert(T entity) {
//This line complete te object child
entity.setChild(em.find(Child.class,entity.getChild().getId()))
entityManager.persist(entity);
return entity.getId();
}
Upvotes: 1