I have two tables
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "car")
public class CarEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
private String name;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "manufacture_id")
private ManufactureEntity manufactureEntity;
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "manufacture")
public class ManufactureEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
There is already an entry named AUDI in the manufacture table. When I try to create a new record
ManufactureEntity manufactureEntity = new ManufactureEntity();
manufactureEntity.setName("AUDI");
CarEntity car = new CarEntity();
car.setName("a6");
car.setManufactureEntity(manufactureEntity);
carService.create(car);
Then I get an error that such a record already exists
org.postgresql.util.PSQLException: ERROR: Duplicate key value violates the "manufacture_name_key" uniqueness constraint
Details: The key "(name)=(AUDI)" already exists.
It turns out that the call to this function is trying to add a new entry to the manufacture table. How do I make this record be created only if it is not there, and if such a record already exists, then the manufacture_id field was simply assigned the key value from the manufacture table?
- When adding a new CarEntity record, how can I specify that its manufacture Entity field will be assigned to an existing record in the manufacture "AUDI" table?
- But if there is no "AUDI" entry in the manufacture table, then you need to create it.
Or is it impossible to implement it at the same time? But only one of the points.
Or do I misunderstand the OneToOne annotation? One entry in the car "a6" table corresponds to only one entry in the manufacturer "AUDI" table. Let's move on. One entry in the car "a8" table corresponds to only one entry in the manufacturer "AUDI" table. Or am I wrong? And here it is necessary to implement ManyToOne.
If I change the OneToOne annotation to ManyToOne, I get the same error
The key "(name)=(AUDI)" already exists.
If I change CascadeType
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
adding to the car table works, but adding to the manufacture table does not work if there is no such record there. I.e. when I specify a specific manufacturer
manufactureEntity.setId(1L);
then writing to the car table occurs without errors. But if I specify an unknown manufacturer
manufacture Entity.setName("AUDIM");
Then I get the error
NULL value in the "manufacture_id" column
With the CascadeType.ALL annotation, it works only if there is no such record in the manufacture table and does not work if there is one. With the CascadeType.MERGE annotation, it works only if there is such an entry in the manufacture table and does not work if there is none.
The question remains open. How do I make an entry in the car table and an entry in the manufacture table work? Or is it simply not possible and I need to manually check the existing records in the manufacture table first and if it is not there, then add it, and then write to the car table?