Я использую Spring + Hibernate JPAA.
У меня есть сущность:
A
id (PK)
Set<B> b;
otherProps…
B
id (PK)
String name; (unique)
otherProps…
, и существует таблица М-М, связывающая A.id, B.id.
, если пользователь создает объект:
A.id = 0
A.b.id = 0
A.b.Name = "Admin";
Сохраняет, но создает новую запись в таблице B. Рассматривайте B как таблицу «Роли», определенную системой, она не должна меняться. Поэтому я хочу, чтобы он снова использовал Admin и автоматически заполнил id. Этот объект происходит из API REST… Ожидается ли в этом случае, чтобы вызывающий абонент знал идентификатор и имя? или они просто должны быть в состоянии заполнить по идентификатору или имени?
Как справиться с этой ситуацией? Или было бы лучше избавиться от идентификатора и иметь имя в качестве PK?
РЕДАКТИРОВАТЬ: уточнить ...
Пользователь сущности Роль сущности Таблица UserRole с User.Id, Роль.Id отношение M2M.
Таблица ролей содержит: 1 пользователя 2 администратора 3 суперпользователя
Это определенная мной таблица fixed . Вызывающему не разрешается добавлять роли.
Так что, если Пользователь1 является Пользователем, тогда в таблице M2M будет запись 1,1.
Теперь представьте, если кто-то проходит вновый пользовательский объект User2 с ролью «Пользователь». Как и сейчас, он создает запись в Roles id = 4 value = User (дублирующаяся запись), а в таблице M2M создает 1,4, где предполагаемое поведение равно 1,1, то есть повторно использует существующего «пользователя»role.
По сути, я думаю, что для вызывающего абонента имеет смысл знать идентификатор пользователя, но я не уверен, имеет ли смысл для вызывающего абонента знать идентификатор роли? кажется, больше похоже, что они будут знать возможные роли. Что-то вроде поведения типа enum?
@ Entity @Table (name = "Customers") открытый класс Customer {
@ApiModelProperty(notes="Id of the customer.", required=true, value="100000")
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long customerId;
@NotNull
@Size(min=2, max=64)
@ApiModelProperty(notes="First name of the customer.", required=true, value="John")
private String firstName;
@NotNull
@Size(min=2, max=64)
@ApiModelProperty(notes="Last name of the customer.", required=true, value="Smith")
private String lastName;
@ManyToMany(cascade={ CascadeType.MERGE })
@JoinTable(name="CustomerRoles",
joinColumns={ @JoinColumn(name="CustomerId") },
inverseJoinColumns={ @JoinColumn(name="RoleId") }
)
private Set<Role> roles = new HashSet<>();
public Long getCustomerId() {
return this.customerId;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<Role> getRoles() {
return new ArrayList<Role>(this.roles);
}
@ Entity @Table (name = "Роли") публичный класс Роль {
@ApiModelProperty(notes="Id of the role.", required=true, value="1")
@Id
//@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long roleId;
@NotNull
@Size(min=2, max=64)
@ApiModelProperty(notes="Name of the role.", required=true, value="Admin")
private String name;
@ManyToMany(mappedBy = "roles")
private Set<Customer> roles = new HashSet<Customer>();
public Long getRoleId() {
return this.roleId;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}