i have a contract class with 3 primary keys, the id is auto_inctement, the convention and the organization are foreign primary keys
@Entity
@IdClass(ContractIdentity.class)
@Table(name = "contract")
public class contract implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@Id
@ManyToOne
private Convention convention;
@Id
@ManyToOne
private Organization organization;
//getter and setter
}
public class ContractIdentity implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long convention;
private Long organization;
//getter and setter
//hashCode and equals
}
first i add a new convention, then i add a new organization, then when i add a new contract i just enter the convention's id and the organization's id
this is the result when i add a new convention
{
"id": 50,
"shortname": "string",
"fullname": "string"
}
this is the result when i add a new convention:
{
"id": 100,
"name": "string"
}
Json for add a new contract:
{
"conventionId": 50,
"organizationId": 100
}
in this step it shows me this error:
detached entity passed to persist: com.back.domain.Convention; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.back.domain.Convention
for mapping i used mapstruct, below is the contract mapping class
@Mapper(uses = { ConventionMapper.class, OrganizationMapper.class })
public interface ContractMapper extends EntityMapper<ContractDTO, Contract> {
@Override
@Mapping(source = "convention.id", target = "conventionId")
@Mapping(source = "organization.id", target = "organizationId")
ContractDTO toDto(Contract contract);
@Override
@Mapping(source = "conventionId", target = "convention")
@Mapping(source = "organizationId", target = "organization")
Contract toEntity(ContractDTO contractDTO);
default Contract fromId(Long id) {
if (id == null) {
return null;
}
Contract contract = new Contract();
contract.setId(id);
return contract;
}
}
this is the method to add a new contract in the service:
@Override
public ContractDTO save(ContractDTO contractDTO) {
Contract contract = ContractMapper.toEntity(contractDTO);
contract = ContractRepository.save(contract);
return ContractMapper.toDto(contract);
}
here is the link to the project in github