Покритикуйте шаблон Java-проекта с DAO для JPA 2
Приветствую!
Не нашёл подходящего топика, решил создать свой. В Интернете видел много туториалов и примеров проектов с использованием Hibernate, DAO-паттерном. В основном попадались специфические для Hibernate реализации с помощью Session Factory, в лучшем случае — с частичным использованием дженериков.
Так как время не стоит на месте, есть спецификация JPA 2.1 с усовершенствованным Criteria API, решил упростить себе жизнь и создал шаблон проекта, который можно быстро наполнить своими сущностями и развернуть RESTful сервис. Пока реализовал с помощью Spring Framework. Хотелось бы узнать у коллег, насколько пригодился бы в профессиональной жизни подобный шаблон на чистом Java EE 7?
Код проекта: github.com/...ec/HibernateSpringDAO2016
14 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів1) Комитить classpath, .settings и прочие IDE/environment специфичный шлак - очень непрофессионально и это уровень trainee, которого еще не выругали за это. помник, сорцы и .gitignore, ну в крайнем случае readme. Все должно собраться из консоли на любом энв-те.
2) пакет dao, внутри пакет daoimpl, но это интерфейс. А ожидается реализация, ведь *impl же.
3) Польза в данном виде сомнительна от такого шаблона.
Специально только что зашёл на Github, проверил: jpaimpl - пакет, вложенный в dao, который содержит в себе класс-реализацию JpaDaoImpl.
Касательно IDE-специфичных файлов - да, для выставляемого на публичное пользование проекта это дурной тон. А если для себя лично, чтобы сэкономить лишнее время?
Спасибо за ревью! А что можно было бы добавить? А методы с конструированием и добавлением Predicate - тоже малополезны? В Интернете видел только примеры с какими-то конкретными классами, а я сторонник универсально написанных методов.
А как такой запрос написать на этом ДАО ?
DB.GetWhere(new User { Login = login, Libraries = { new Library { Name = libName, Subscribers = { new Subscriber { IsActive = true } } } } }) .Join(new User { Libraries = { new Library { Subscribers = { new Subscriber { Login = "" } } } } }, new User { Login = "" }) .Insert(new User { Events = { ev } }, Change.CreateOne(ev, ChangeEnum.Add), JoinedEnum.SecondTable);Его суть, У пользователя есть библиотеки (Library). У библиотеки есть список подписчиков (Subscribers). Когда библиотека поменялась, всем подписчикам этой библиотеки нужно добавить в коллекцию (Events) событие (ev).
Очень похоже на то, что обычно делает триггер. Если вся информация, которая необходима, уже есть в сущности перед сохранением, думаю, можно в классе сущности написать метод и пометить его аннотациями javax.persistence.PrePersist и javax.persistence.PreUpdate.
В самом методе я бы сделал что-то вроде этого:
Event ev = new Event(ChangeEnum.Add); this.getLibraries().forEach(l -> { l.getSubscribers().forEach(s -> s.getEvents().add(ev)); });Это, конечно, если библиотеки и подписчики примаплены к пользователю и в сущностях настроен полный каскадинг.
Очень похоже на говнокод. Ибо в Днипре уйдет один запрос на сервер, а у вас много запросов будут досить сервер
Согласен, по-хорошему в библиотеках не должно быть явной ссылки на коллекцию подписчиков. Я предварительно смотрел, как через JPA Criteria API писать соединения таблиц, на практике пока не пробовал. Довольно многословно получается, но, ИМХО, проще, чем следить за фигурными скобками.
А зачем следить за фигурными скобками, это статическая типизация.
Это когда у тебя модель в базе данных поменялась на лету, а компилятор тебе синтаксическими ошибками показал что в твоих «хранимках» нужно поправить прямо на этапе компиляции.
Кстати, а что это за DSL/фреймворк такой?
Это обычный .NET
Неожиданно ))
Через триггер нельзя ведь эвент содержит инфо о инициаторе эвента
Controller: ation/RestController.html
— если пишешь @RestController, то @ResponseBody не нужен docs.spring.io/...
Дальше, честно, лень смотреть :)
Спасибо, не досмотрел. Поменял на ResponseEntity.