#java #mysql #hibernate #jpa
#java #mysql #гибернация #jpa
Вопрос:
Я пытаюсь выполнить простое отображение, но у меня возникают проблемы.
По сути, то, что у меня есть в Mysql, — это таблица пользователей всего с одним столбцом, который является varchar(255)
именем Username, являющимся первичным ключом.
У меня есть еще одна таблица под названием notes, которая имеет первичный автоматически генерируемый ключ, представляющий собой столбцы int
, date
столбец, varchar
name и contents, а также varchar(255)
вызываемый owner, который должен содержать имя пользователя.
Это помечено как внешний ключ, ссылающийся на пользователей (имя пользователя).
Код для получения фабрики сеансов следующий:
private static SessionFactory createSessionFactory() {
SessionFactory sessionFactory;
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
configuration.addAnnotatedClass(Note.class);
configuration.addAnnotatedClass(User.class);
StandardServiceRegistry serviceRegistry = new
StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
Это отлично работает без строки, которая добавляет аннотированный класс ‘Note’, так что, вероятно, проблема в этом классе. Ошибка заключается в следующем:
Не удалось получить конструктор для org.hibernate.persister.entity.Организация SingleTableEntityPersister.hibernate.Исключение MappingException
Полная трассировка стека:
Полные классы доступны здесь:
ОБНОВЛЕНИЕ: исправлено неправильное название переменной Owner / OwnerName однако теперь я получаю эту ошибку: ОШИБКА:
Не удается добавить или обновить дочернюю строку: сбой ограничения внешнего ключа (
notes
.notes
, ССЫЛКИ наnotes_ibfk_1
ВНЕШНИЙ КЛЮЧ (Owner
) ОГРАНИЧЕНИЯusers
(username
))
Комментарии:
1. Поделитесь Note.java код
2. @Vigneshwaran hastebin.com/olekofonun . java вот оно
3. Трассировки стека недостаточно. Пожалуйста, поделитесь полной трассировкой стека, которая содержит «вызвано»
Ответ №1:
Проблема в классе Note. Для владельца переменной имя метода установки неверно. Вместо
public void setOwnerName(String u) {
this.owner = u;
}
Это должно быть
public void setOwner(String u) {
this.owner = u;
}
Это должно решить проблему.
Комментарии:
1. Спасибо, это исправило первую ошибку, однако теперь у меня возникает эта ошибка при попытке запуска: ОШИБКА: Не удается добавить или обновить дочернюю строку: сбой ограничения внешнего ключа (
notes
.notes
, ССЫЛКИ наnotes_ibfk_1
ВНЕШНИЙ КЛЮЧ (Owner
)users
(username
))2. Можете ли вы поделиться своим hibernate.cfg.xml файл? Вы определили там какую-то конфигурацию?
3. hastebin.com/foruvaleke.xml вот оно. Также вот описание sql в таблице notes на случай, если это актуально: hastebin.com/atalixosaz.rb
4. хорошо. Возможно, я обнаружил проблему. Сначала попробуйте сохранить пользователя, а затем отметьте в своем методе testSave
Ответ №2:
вы должны сначала сохранить user, а затем сохранить note в своем тестовом классе. ваш код должен быть таким.
@Test
public void testSave() {
Session session = factory.openSession();
Date date = Date.valueOf(LocalDate.now());
User user = new User("Joseph");
Note note = new Note();
note.setName("Joseph's note");
note.setContents("blah blah blah");
note.setOwnerName("Joseph");
session.beginTransaction();
session.save(user);
session.save(note);
session.getTransaction().commit();
session.close();
System.out.println(date);
}
но с этим кодом у вас просто есть внешний ключ в базе данных, и у вас нет отношения в вашем коде.
ваша заметка может быть похожа на приведенный ниже код.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "username")
public String getOwner() {
return owner;
}
наконец, ваш тестовый класс может быть похож :
@Test
public void testSave() {
Session session = factory.openSession();
Date date = Date.valueOf(LocalDate.now());
User user = new User("Joseph");
Note note = new Note();
note.setName("Joseph's note");
note.setContents("blah blah blah");
note.setOwner(user);
session.beginTransaction();
session.save(user);
session.save(note);
session.getTransaction().commit();
session.close();
System.out.println(date);
}
Комментарии:
1. Большое вам спасибо, этот ответ очень информативен. Проголосовал против, но принял другой ответ, потому что он решил проблему первым
2. Всегда пожалуйста 😉