У меня проблема с отношениями "многие ко многим". Таблицы: ингредиент и пищевая ценность. Я создал таблицу отношений между двумя объектами, в которой есть внешние ключи ингредиента и пищевой ценности (которые образуют составной ключ) и некоторые атрибуты.
Класс JoinedNutrionalValueIngredient:
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Entity @Data
public class JoinedNutrionalValueIngredient implements Serializable {
@EmbeddedId
private NutrionalValueIngredientId id;
@ManyToOne(fetch= FetchType.LAZY)
@MapsId("ingredient_id")
private Ingredient ingredient;
@ManyToOne(fetch=FetchType.LAZY)
@MapsId("nutrional_value_id")
private NutrionalValue nutrionalValue;
@NotNull
String matrixUnit;
@NotNull
int value;
@NotNull
String valueType;
}
Класс NutrionalValueIngredientId:
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
@Embeddable
@Getter
@Setter
public class NutrionalValueIngredientId implements Serializable{
@Column(name = "ingredient_id")
private Long ingredient_id;
@Column(name = "nutrional_value_id")
private Long nutrional_value_id;
public NutrionalValueIngredientId() {
}
public NutrionalValueIngredientId(Long ingredient, Long nutrionalValue){
this.ingredient_id=ingredient;
this.nutrional_value_id=nutrionalValue;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
NutrionalValueIngredientId that = (NutrionalValueIngredientId) o;
return Objects.equals(ingredient_id, that.ingredient_id) &&
Objects.equals(nutrional_value_id, that.nutrional_value_id);
}
@Override
public int hashCode() {
return Objects.hash(ingredient_id, nutrional_value_id);
}
}
Когда я пытаюсь вставить новое поле в таблицу отношений, я получаю эту ошибку:
{
"timestamp": 1542653896247,
"status": 500,
"error": "Internal Server Error",
"message": "Could not set field value [1] value by reflection : [class com.whateat.reciper.model.NutrionalValueIngredientId.ingredient_id] setter of com.whateat.reciper.model.NutrionalValueIngredientId.ingredient_id; nested exception is org.hibernate.PropertyAccessException: Could not set field value [1] value by reflection : [class com.whateat.reciper.model.NutrionalValueIngredientId.ingredient_id] setter of com.whateat.reciper.model.NutrionalValueIngredientId.ingredient_id",
"path": "/v1/joinedNutrionalValueIngredients"
}
Обновлено: я добавил конструктор и аннотацию @Getter и @Setter, но у меня такая же ошибка.
класс NutritionalValue:
@Data
@Entity
public class NutrionalValue implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String name;
@NotNull
private String unit;
@NotNull
private String source;
@ManyToOne
@NotNull
@JoinColumn(name = "category_id")
private NutrionalValueCategory category;
@OneToMany(mappedBy = "nutrionalValue")
private Set<JoinedNutrionalValueIngredient> joined = new HashSet<JoinedNutrionalValueIngredient>();
}
редактировать: после ответа Debopam эта ошибка вылезла.
{
"timestamp": 1542657216244,
"status": 500,
"error": "Internal Server Error",
"message": "null id generated for:class com.whateat.reciper.model.JoinedNutrionalValueIngredient; nested exception is org.hibernate.id.IdentifierGenerationException: null id generated for:class com.whateat.reciper.model.JoinedNutrionalValueIngredient",
"path": "/v1/joinedNutrionalValueIngredients"
}
Я пробовал, но получаю ту же ошибку.
Еще одна вещь, вы забыли добавить требуемый конструктор по умолчанию. Проверить это
Не могли бы вы поделиться классом NutritionalValue




Измените имена переменных, как показано ниже
Длинный ингредиент_ид в Длинный ингредиентид nutrional_value_id в nutrionalvalueid
Пример
@Column(name = "ingredient_id")
Long ingredient_id;
к
@Column(name = "ingredient_id")
Long ingredientid;
Затем сгенерируйте геттер-сеттер для всех полей. Hibernate не может установить поля, потому что нет общедоступного получателя / установщика.
Спасибо за ответ. Я изменил названия переменных, теперь получил еще одну ошибку.
Задайте значения для идентификатора объекта «NutrionalValueIngredientId», затем попробуйте вставить его как встроенный идентификатор для «JoinedNutrionalValueIngredient». см. пример ниже:
package com.example;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class EmployeeId implements Serializable
{
private static final long serialVersionUID = 1L;
@Column(name = "EMP_ID")
private int empId;
@Column(name = "DEPARTMENT")
private String department;
public EmployeeId()
{
super();
}
public EmployeeId(int empId, String department)
{
super();
this.empId = empId;
this.department = department;
}
public int getEmpId()
{
return empId;
}
public void setEmpId(int empId)
{
this.empId = empId;
}
public String getDepartment()
{
return department;
}
public void setDepartment(String department)
{
this.department = department;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((department == null) ? 0 : department.hashCode());
result = prime * result + empId;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EmployeeId other = (EmployeeId) obj;
if (department == null)
{
if (other.department != null)
return false;
} else if (!department.equals(other.department))
return false;
if (empId != other.empId)
return false;
return true;
}
}
См. Выше Embedded Id class (EmployeeId). который является первичным ключом класса Employee. Итак, нам нужно установить значения в классе Id (EmployeeId). Затем ввести этот класс идентификатора в Employee в качестве первичного ключа. Тогда все заработает. Без первичного ключа это значение равно нулю.
package com.example;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Employee implements Serializable
{
private static final long serialVersionUID = 1L;
@EmbeddedId
EmployeeId id;
@Column(name = "EMP_NAME")
private String empName;
public Employee()
{
super();
}
public Employee(EmployeeId id, String empName)
{
super();
this.id = id;
this.empName = empName;
}
public EmployeeId getId()
{
return id;
}
public void setId(EmployeeId id)
{
this.id = id;
}
public String getEmpName()
{
return empName;
}
public void setEmpName(String empName)
{
this.empName = empName;
}
}
Задайте значения для класса Id и другого поля, как показано ниже.
//Create a new Employee object
Employee employee = new Employee();
EmployeeId employeeId = new EmployeeId(1,"DailyNews");
employee.setEmpName("CompositeKey");
employee.setId(employeeId);
session.save(employee);
При использовании Spring Data Rest автоматически генерировались необработанные операции. однако предложенное нам решение заставило бы меня переписать метод публикации. что я хотел бы сделать, так это вставить эту таблицу непосредственно из вызова rest. @Roshini
Убедитесь, что вы устанавливаете экземпляр для встроенного идентификатора. У меня не было этой ошибки.
Я меняю это
@EmbeddedId
ProductUserId id;
ProductUser(Integer productId, Integer UserId, Double rating){
this.rating = rating
}
к
@EmbeddedId
ProductUserId id;
ProductUser(Integer productId, Integer userId, Double rating){
this.id = new ProductUserId(productId, userId);
this.rating = rating
}
@Entity @Data
public class JoinedNutrionalValueIngredient implements Serializable {
@EmbeddedId
private NutrionalValueIngredientId id = new NutrionalValueIngredientId();
// ... rest of class
}
В классе JoinedNutrionalValueIngredient должен быть инстанциирован идентификатор соединения NutrionalValueIngredientId .
Это то, что мне пришлось сделать. Я заполнял свой эквивалент «ингридиента» и «нутрионального значения» и получал исключение «Не удалось установить поле ...» при сохранении. Для меня проблема была решена.
Ваши поля NutrionalValueIngredientId защищены пакетом, вам нужно сделать их частными и добавить геттеры / сеттеры (вручную (например, с помощью генератора ide)) или использовать lombok.