Меня заблокировали в моем проекте. Я не могу получить sql запросов для работы с классом «@Embeddable». У меня есть класс «Пользователь», у которого есть несколько «Предпочтений»
package com.donation.rest.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Pattern;
import com.donation.rest.converter.RightConverter;
import com.donation.rest.dto.UserDTO;
import com.donation.rest.enums.RightsEnum;
@Entity
@Table(name = "users")
public class User extends DateModel implements IModel {
private static final long serialVersionUID = 6678092850253642056L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "USER_ID", unique = true, updatable = false, nullable = false)
private Long id;
@Column(name = "USER_NAME", unique = true, nullable = false)
@Pattern(regexp = "^[a-zA-Z0-9]*$")
private String name;
@Column(name = "USER_PASSWORD", nullable = false)
private String password;
@ElementCollection(targetClass = RightsEnum.class, fetch = FetchType.EAGER)
@CollectionTable(name = "users_rights", joinColumns = @JoinColumn(name = "USER_ID"))
@Column(name = "RIGHTS", nullable = false)
@Convert(converter = RightConverter.class)
private Set<RightsEnum> rights = new HashSet<RightsEnum>();
@OneToMany(mappedBy = "preferenceId.user", cascade = CascadeType.REMOVE)
private Set<Preference> preferences = new HashSet<Preference>();
public User() {
super();
}
public User(Long id, String name, String password, Set<RightsEnum> rights, Set<Preference> preferences) {
super();
this.id = id;
this.name = name;
this.password = password;
this.rights = rights;
this.preferences = preferences;
}
public User(UserDTO userDTO) {
this.setName(userDTO.getName());
this.setPassword(userDTO.getPassword());
this.setRights(userDTO.getRights());
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<RightsEnum> getRights() {
return rights;
}
public void setRights(Set<RightsEnum> rights) {
this.rights = rights;
}
public Set<Preference> getPreferences() {
return preferences;
}
public void setPreferences(Set<Preference> preferences) {
this.preferences = preferences;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + ", rights=" + rights + ", preferences="
+ preferences + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof User))
return false;
User other = (User) obj;
if (id == null) {
if (other.getId() != null)
return false;
} else if (!id.equals(other.getId()))
return false;
return true;
}
}
У меня есть класс «Предпочтение», в котором используются два первичных ключа: пользователь и ключ (перечисление). Поэтому я использую аннотацию @EmbeddedId и объявляю PreferenceId.
package com.donation.rest.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
@Entity
@Table(name = "preferences")
public class Preference implements Serializable {
private static final long serialVersionUID = 6320680839053872351L;
@EmbeddedId
private PreferenceId preferenceId;
@Column(name = "PREFERENCE_VALUE", nullable = false)
@Type(type = "text")
private String value;
public Preference() {
super();
}
public Preference(PreferenceId preferenceId, String value) {
super();
this.preferenceId = preferenceId;
this.value = value;
}
public PreferenceId getPreferenceId() {
return preferenceId;
}
public void setPreferenceId(PreferenceId preferenceId) {
this.preferenceId = preferenceId;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Preference [preferenceId=" + preferenceId + ", value=" + value + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((preferenceId == null) ? 0 : preferenceId.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Preference other = (Preference) obj;
if (preferenceId == null) {
if (other.preferenceId != null)
return false;
} else if (!preferenceId.equals(other.preferenceId))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
Затем класс «PreferenceId», который является «@Embeddable».
package com.donation.rest.model;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.donation.rest.enums.PreferencesEnum;
@Embeddable
public class PreferenceId implements Serializable {
private static final long serialVersionUID = 5641070814677067804L;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "USER_ID", nullable = false)
private User user;
@Enumerated(EnumType.STRING)
@Column(name = "PREFERENCE_KEY", updatable = false, nullable = false)
private PreferencesEnum key;
public PreferenceId() {
super();
}
public PreferenceId(User user, PreferencesEnum key) {
super();
this.user = user;
this.key = key;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public PreferencesEnum getKey() {
return key;
}
public void setKey(PreferencesEnum key) {
this.key = key;
}
@Override
public String toString() {
return "PreferenceId [user=" + user + ", key=" + key + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PreferenceId other = (PreferenceId) obj;
if (key != other.key)
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
}
У меня есть контроллер, который возвращает значение предпочтения с идентификатором пользователя и ключевым параметром.
Контроллер
Далее идет служба. Здесь начинаются мои проблемы. Я протестировал множество вызовов из репозитория jpa, которые я прокомментировал.
Сервис
Здесь репозиторий:
Репозиторий
Предпочтение, которое я хочу получить из базы данных:
- Предпочтительный ключ: LANGUAGE
- Предпочтительный идентификатор пользователя: 1
- Значение предпочтения: fr
Теперь запрос, который я использовал в почтальоне:
Request
И вот ошибка с запросом Hibernate сделали. Я не понимаю. Он дублирует поля, а также не использует встроенное поле идентификатора (он не выполняет «preference.preferenceId.user.userId» и «preference.preferenceId.key»).
Ошибка
Что я пропустил? Что я сделал не так? Я просмотрел все это на inte rnet, все проверил, просто не могу ... В противном случае я использовал "Embeddedid" вместо "IdClass", чтобы избежать дублирования геттеров и сеттеров.
Спасибо вам, ребята.