Попробуйте десериализвать объект сразу после сериализации, на сервере - и посмотреть его состояние. Это поможет локализовать проблему (на сервере или на клиенте). А вообще, для клиент-серверного взаимодействия лучше использовать JSON/REST - достаточно быстрый/экономный, плюс очень прост в отладке, т.к. результат сериализации человекочитабелен.
Константин: Изучать язык делая рефакторинг - сомнительный вариант, хотя есть и плюс - решается конкретная задача а не нечто в вакууме... Насчёт "новый движок" - технология JSP устарела лет 10 назад, на смену ей пришли Java Server Faces. Насчёт URL, наверное как-то так: urlPatterns = "/project/*"
А зачем вообще лишнее звено в виде сервлета? JSP-страница тоже имеет доступ к объекту HttpServletRequest, почему бы не делать всю работу там? Можно, например, добавить в URL параметр, затем на странице project.jsp извлекать его из HttpServletRequest и отрабатывать вашу логику
Виталий Столяров: У Вас какая-то мешанина в голове. Попробуйте просто реализовать так, как в моём ответе, создав одну таблицу на все варианты Field. create table fileds (val1 varchar(10), min int, max int, some_date date, ...). Откуда могут взяться джойны, если таблица одна? Включите трассировку SQL в Hibernate и посмотрите запросы. При выборке SliderField будет select val1, min, max from fileds. При выборке DateField будет select val1, some_date from fileds.
Разделение на множество таблиц может усложнить решение в целом, а также есть вероятность впоследствии получить неприятные побочные эффекты, например, вы не можете 100% защититься от случая, при котором запись в таблице-расширении удаляется, а соответствующая ей запись в базовой таблице остаётся. Получается так называемая осиротевшая запись. К тому же, Вы упоминали о том, что много JOIN-ов нежелательно (поддерживаю это мнение), но как вы соберете данные из пар таблиц без джойнов? Вообще, реляционные СУБД не очень подходят для построения иерархических структур. Я бы порекомендовал сделать всё одной таблицей - так проще и надёжнее, а если накладные расходы на null Вас не беспокоят, то серьёзных минусов вообще не вижу.
Виталий, Вы писали "если делать их отдельными Entity, но это получится не хорошо со стороны структуры БД", теперь пишете что "в одной таблице ... будет много NULL (пустых) полей". Вы всё же в первую очередь определитесь со структурой таблиц в БД, а уж затем решайте как их правильно замапить. Я ответил на конкретный вопрос о построении маппингов на основе имеющейся информации. Судя по всему, Вам следует задать другой вопрос, о том, как правильнее построить структуру таблиц БД. Насчёт пустых полей - многое зависит от СУБД, например, в Oracle они не занимают места, насчёт других СУБД не смотрел (Гугл в помощь). Если в выбранной Вами СУБД под null место расходуется, то перед вами дилемма: либо тратить больше места, но меньше нагружать БД джойнами, либо наоборот.
Вам бы желательно перед тем, как делать сложные маппинги, попробовать что-то попроще, чтобы понять как вообще работает JPA. Сущности проецируются на запись в таблице БД в тот момент, когда вы вызываете методы чтения/изменения данных, например, EntityManager.persist. Если сильно упрощать, то в этот момент EntityManager "сканирует" метаданные класса (аннотации) и узнаёт имя таблицы и имя полей, которые требуется сохранить. Т.е., что описано в классе (и его родительских классах), то и будет сохранено. При этом не имеет значения, сколько классов содержат в себе информацию об одной и той же таблице. PS toster.ru - это ресурс вопрос и ответов, а не обучающих материалов.
Недостаточно данных в вопросе для точного ответа: описана сторона Object из концепции Object-Relational Mapping, но ничего не сказано про Relational, т.е. не видна структура таблиц БД. SliderField и DateField - это отдельные таблицы?
Я описал общий случай. Всё зависит от бизнес-логики вашего ПО, вы сами должны решить какие части операции должны быть атомарными. Комментарии уже ушли от темы вопроса, не вижу смысла продолжать дискуссию.
Транзакция всегда должна создаваться новая, тут речь идёт не о производительности, а о консистентности и атомрности. Создание сессии может влиять на производительность и скорость, поэтому обычно используется пул сессий. Метод SessionFactory.openSession() определён в интерфейсе, и в случае использования пула, реализация этого интерфейса обычно берет сессию из пула, а не создаёт новую. Также и Session.close() в таких случаях просто возвращает сессию в пул (отмечает как свободную) без фактического разрыва соединения с БД. Долго неиспользуемые сессии обычно удаляются из пула, закрывая соединение с БД. Реализация такого поведения ложится на "движок" пула, их существует множество. Вам, как прикладному программисту в этом разбираться не обязательно, главное убедиться в том, что пул у вас есть (если беспокоит производительность).
Обычно, либо все действия выполняются в одной транзакции и подтверждаются одним commit-ом, либо откатываются все одним rollback-ом. В случае отката сообщение передаётся клиенту (пользователю или Системе). Стандартный код выглядит примерно так:
Session session = null;
Transaction tx = null;
try {
session = sessionFactory.openSession();
tx = session.beginTransaction();
//do some work
tx.commit();
} catch (Exception e) {
e.printStackTrace();
if (tx != null && tx.isActive()) {
try {
tx.rollback();
} catch (Exception ignored) {
}
}
throw e;
} finally {
if (session != null && session.isOpen()) session.close();
}
Больше вариантов нет. Похоже на то, что проблема специфична для вашего ПО, а не в Hibernate или в MySQL. Смотрите под отладкой или добавьте тотальную трассировку в лог всего происходящего, чтобы понять чем отличаются случаи корректного сохранения от случаев с ошибками. Например, у вас подозрительная обработка ошибок - сразу начинается новая транзакция: это противоречит принципам атомарности, плюс может привести к неконсистентности данных сессии.
Констрейнты создаются базой данных в ответ на вашу команду. При создании таблицы поле первичного ключа должно быть объявлено примерно так: ID BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT. Ключевой момент здесь - AUTO_INCREMENT. Узнать структуру таблицы можно командой DESCRIBE имя_таблицы;. Будет выведен список полей таблицы, для первичного ключа в столбце EXTRA должно быть значение auto_increment
Еще вариант: GenerationType.IDENTITY подразумевает автоинкремент на уровне поля БД. Возможно, в какой-то из таблиц соответствующие констрейнты не созданы.
1. JSP - технология прошлого века (дата выхода - 1999), уже много лет считается устаревшей (спецификация-преемница JSP - JSF, вышла в 2004-м, 12 лет назад). Не стоит ворошить прошлое, если нет на то серьёзных причин.
2. В спецификациях CDI нет никаких упоминаний JSP. Даже если у вас будет работать смешение JSP и CDI сегодня, нет никаких гарантий того, что это будет продолжать работать завтра: после очередного обновление версий библиотек всё может "рухнуть". Не стоит делать Франкенштейна.
вот это не пробовали: stackoverflow.com/a/22473167/1341148 ?
если у Вас первичные ключи в БД автоинкрементные, то надо сущности описывать так:
@GeneratedValue(strategy = GenerationType.IDENTITY)
Куликов Александр: "узнайте чем там занимаются" - за всех не скажу, я на первое место работы устроился не зная ни одной из коньюктурных технологий. Просто пришёл и рассказал как вливался в программирование, что понял, что умею... Если автор вопроса (как и многие другие) решил стать программистом просто потому, что там хорошо платят - его не ждёт успех, впрочем, и в любой другой специальности ситуация такая же. В любой сфере много людей, которые попали туда по ошибке, и это не страшно - все ищут себя и растут. А автору вопроса, вместо того, чтобы гоняться за модой, порекомендовал бы эту коротенькую статью - www.williamspublishing.com/21-days.html. Она не столько про программирование, сколько про жизнь вообще...
"используется фреймворк Spring". Spring и Java EE - это две очень похожих возможности реализовать одно и то же, но есть одно большое НО: Spring - это НЕ Java EE, поэтому Ваш ответ неверен.
"а если там много ресурсов, неужели ради одного файла, всё перегружать?" - я делал упор на промышленную среду, а её, обычно, обновляют не каждый день. При частичной сборке какие-то изменения могут быть забыты.
"как обстоит дело с безопаснотью" - тут развёрнуто ответить не смогу, т.к. предпочитаю деплоить по старинке - заменять приложение в файловой системе. Вообще, безопасность в Wildfly достаточно развита, коннекторы можно гибко конфигурировать, в т.ч. настройки безопасности: SSL, домены безопасности, источники информации о пользователях/паролях. Вот, например, выдержка из Руководства Администратора Wildfly: WildFly 8 is now distributed secured by default. The default security mechanism is username / password based making use of HTTP Digest for the authentication process
mrkovalchuk: "не работает" - понятие растяжимое. Если возникает всё та же ошибка - попробуйте развернуть всё "с нуля", очистив таблицы. Плюс в виду отсутствия сведений о других таблицах, я удалил из маппинга Note всё, кроме Id и telephoneId. Попробуйте сделать также, если заработает - возвращайте поля по одному и смотрите на каком из полей "сломается".
PS Связь one-to-one - вещь довольно редкая, ваши данные можно хранить в одной таблице и всё будет намного проще. Если на то нет каких-то архитектурных причин, я бы порекомендовал хранить одну сущность в одной таблице...