我有一个Phone实体和一个PhoneType实体。每个电话都有1个电话类型,每个电话类型可以有许多电话。
我想在使用现有PhoneType时添加新Phone,但是当我创建新Phone时,如何在不从数据库检索PhoneType且不更新现有PhoneType的情况下与现有PhoneType创建关系?< / p>
我尝试仅使用现有ID创建新的PhoneType,然后尝试更新PhoneType记录。我不希望发生此更新。
我也尝试过在Phone的PhoneType字段上更改CascadeType,但是我很难理解这些不同类型的功能。
在“电话”实体中:
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "phone_type_id", referencedColumnName = "id")
private PhoneType phoneType;
以及PhoneType实体:
@Getter
@Setter
@EqualsAndHashCode
@Entity
@Table(name = "phone_type")
public class PhoneType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "description", length = 175, nullable = false)
private String description;
@Column(name = "name", length = 175, nullable = false)
private String name;
}
最后,创建实体/关系:
return new Phone()
.setNumber(phoneNumber)
.setPhoneType(new PhoneType().setId(defaultPhoneTypeId))
}
在这种情况下,所发生的正是您所期望的,hibernate尝试使用一堆空字段(其中PhoneType id = defaultPhoneTypeId)更新PhoneType。
使用CascadeType.MERGE,出现以下错误:
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.phoneType -> com.PhoneType
虽然这是预期的,但我不知道如何使用1个新实体和1个现有实体创建关系。
答案 0 :(得分:0)
您已将级联类型指定为CascadeType.ALL
这会将所有操作级联到映射的实体。
因此,在保存电话时,您将级联保存操作并要求ORM也保存电话类型。
尝试将其完全删除。默认级联类型级联无操作。
@ManyToOne
@JoinColumn(name = "phone_type_id", referencedColumnName = "id")
private PhoneType phoneType;
在创建电话对象时,您可以从数据库中通过ID获取phoneType,然后在保存之前将其设置在电话对象中。