-->

Many-To-Many by IntelliJ IDEA

Создание сущностных POJO-классов в IntelliJ IDEA из таблиц базы данных с отношением Многие-Ко-Многим:

  1. Выбрать вторую таблицу отношения (первая уже выбрана);
  2. Прописать имя свойства, которое должно быть добавлено к этому объекту из другой сущности, - groupSet;
  3. Прописать имя свойства, которое должно быть добавлено к этому объекту из другой сущности, - userSet;
  4. Выбрать тип свойства - Set<> (в случае М2М);
  5. Выбрать служебную, связывающую таблицу (Join Table);
  6. Сопоставляем ключевые поля связанных таблиц с полями связывающей.
@Entity
public class User {
    private int id;
    private String username;
    private String password;
    private Set<Group> groupSet;

.....

    @ManyToMany
    @JoinTable(name = "link_user_group",
            joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false),
            inverseJoinColumns = @JoinColumn(name = "group_id", referencedColumnName = "id", nullable = false))
    public Set<Group> getGroupSet() {
        return groupSet;
    }

    public void setGroupSet(Set<Group> groupSet) {
        this.groupSet = groupSet;
    }
}

@Entity
public class Group {
    private int id;
    private String name;
    private Set<User> userSet;

.....

    @ManyToMany(mappedBy = "groupSet")
    public Set<User> getUserSet() {
        return userSet;
    }

    public void setUserSet(Set<User> userSet) {
        this.userSet = userSet;
    }
}

IntelliJ IDEA + Spring

Добавление namespace в конфигурационные XML-файлы контекста Spring при работе в IntelliJ IDEA.

Создаем XML-файл конфигурации контекста Spring. По-умолчанию сразу создается пространство имен (namespace) beans. Для добавления, например, пространства имен context необходимо ввести первые буквы имени параметра данного context и нажать Ctrl-Alt-Space, если подсказка не появилась:
cs [Ctrl-Alt-Space] -> <context:component-scan>

Настройка Eclipse

После установки Eclipse настоятельно рекомендуется произвести некоторые настройки для "облегчения жизни". Привожу здесь свои предложения.
1. General -> Editors -> Text Editors -> Spelling -> Encoding = UTF-8;
2. General -> Web browser = Use external web browser, Ghrome;
3. General -> Workspace -> Save automatically before build, Text file encoding = UTF-8;
4. Java -> Code Style -> Active profile -> New..., (enter name), Edit -> Line Wrapping -> Maximum line width = 250;
5. Java -> Compiler -> JDK Compliance = 1.8;
6. Java -> Editor -> Content Assist -> Completion overwrites, Auto activation trigger for Java = .abcdefghijklmnopqrstuvwxyz;
7. Java -> Editor -> Save Action -> Perform the selected actions on save, Format all lines, Additional actions;
8. Java -> Editor -> Typing -> Automatically insert at correct position = semicolons;
9.

Полезные plug-in:
1. ResourceBundle Editor - редактор файлов локализации
https://raw.githubusercontent.com/essiembre/eclipse-rbe/master/eclipse-rbe-update-site/site.xml
2. DBeaver - работа с базами данных.
Устанавливается через Marketplace. После установки появляется пункт меню Database. Панель DBeaver выводится через Window -> Show View -> Other... -> Database -> Database Navigator
3. 

Spring IDE

Вообще не понял почему так понравившаяся мне IntelliJ IDEA так недружелюбно относится к программистам, использующим Spring! Может быть, конечно, я просто с чем-то не разобрался, но факт в том, что когда я увидел видео-уроки по Spring'у с использованием IDE Eclipse, то первая мысль была: "А что, так можно было?!"

Что же так меня впечатлило.
Основное - это работа с XML-файлами настроек Sping, коих в этом Spring'е предостаточно. Кстати, единственное объяснение, которое я могу найти, почему в IntelliJ IDEA нет аналогичного функционала, - работа со Spring с помощью аннотаций.
Приведу наглядные примеры.

1. Различное дружественное отображение XML-файлов. На примере pom-файла Mavena.
"Голый" pom-файл:
Обратите внимание на закладки внизу. Можно отобразить этот файл в виде такой формы настроек:
Даже на первый взгляд видно, как удобно настраивать или изменять параметры pom-файла.
Можно, например, визуально увидеть все зависимости:
Также можно посмотреть так называемый эффективный pom-файл.

2. Еще интереснее с XML-файлами Spring.
Естественно, можно увидеть и редактировать непосредственно текст XML-файла:
Либо в режиме различных форм отображения, например:
Можно даже увидеть графическое отображение бинов:
И самое, на мой взгляд, полезное - добавление необходимых схем, что для новичков вообще не понятно, а опытных программеров заставляет тупо копи-пастить:


Существуют два варианта установки Eclipse для работы со Spring: "стоковый" Eclipse + необходимые плагины, либо установка STS (Spring Tool Suite) - по сути тот же самый Eclipse уже с необходимыми плагинами и различными преднастройками.

Любителям IntelliJ IDEA могу на данный момент посоветовать только создавать проект Spring в Eclipse, а затем работать с ним в IntrlliJ IDEA. Хотя сам таким образом еще не пробовал, но очевидных сложностей не вижу.

Hibernate. Отношения ManyToOne (OneToMany) Unidirectional и Bidirectional

Отношения между Java-объектами и таблицами базы данных Один-ко-многим.

Существует три вида отношений между таблицами реляционных баз данных:
  • One-to-One,
  • One-to-Many / Many-to-One,
  • Many-to-Many.

Отношения Один-ко-многим - наиболее распространенный вид отношений .
Практическим примером таких отношений могут служить такие пары сущностей, как
  • Наниматель (один) - Работник (много);
  • Покупатель (один) - Товар (много);
  • Курс (один) - Студент (много);
  • Адрес (один) - Студент (много), т.е. по одному адресу могу проживать не менее одного студента, а каждый студент имеет только один адрес проживания:
или в виде таблиц БД:
Такого рода отношения в Hibernate обозначаются аннотациями @ManyToOne или @OneToMany, в зависимости от Java-класса, описывающего сущность, в котором они применяются.

Помимо этого, все отношения в Hibernate могут быть однонаправленными (Unidirectional) и двунаправленными (Bidirectional).

Посмотрим на примере.
Создадим два Java-класса, которые объявим сущностями Hibernate с помощью аннотации @Entity. А также поля, используемые для идентификации этих сущностей, и сопоставленные со столбцами соответствующих таблиц при помощи аннотаций @Id и @GeneratedValue.

Кроме того, в классе Student объявлена переменная address класса Address.

Address.java

  1. import javax.persistence.Entity;  
  2. import javax.persistence.GeneratedValue;  
  3. import javax.persistence.GenerationType;  
  4. import javax.persistence.Id;  
  5.   
  6. @Entity  
  7. public class Address {  

  8.     private Long id;  
  9.     private String address;  
  10.       
  11.     @Id  
  12.     @GeneratedValue(strategy=GenerationType.AUTO)  
  13.     public Long getId() {  
  14.         return id;  
  15.     }  

  16.     public void setId(Long id) {  
  17.         this.id = id;  
  18.     }  

  19.     public String getAddress() {  
  20.         return address;  
  21.     }  

  22.     public void setAddress(String address) {  
  23.         this.address = address;  
  24.     }  
  25. }  

Student.java

  1. import javax.persistence.Entity;  
  2. import javax.persistence.GeneratedValue;  
  3. import javax.persistence.GenerationType;  
  4. import javax.persistence.Id;  
  5.   
  6. @Entity  
  7. public class Student {  

  8.     private Long id;  
  9.     private String studentName;  
  10.     private Address address;  
  11.       
  12.     @Id  
  13.     @GeneratedValue(strategy=GenerationType.AUTO)  
  14.     public Long getId() {  
  15.         return id;  
  16.     }  

  17.     public void setId(Long id) {  
  18.         this.id = id;  
  19.     }  

  20.     public String getStudentName() {  
  21.         return studentName;  
  22.     }  

  23.     public void setStudentName(String studentName) {  
  24.         this.studentName = studentName;  
  25.     }  
  26.       
  27.     public Address getAddress() {  
  28.         return address;  
  29.     }  

  30.     public void setAddress(Address address) {  
  31.         this.address = address;  
  32.     }  
  33. }  

При создании экземпляров данных классов, в объектах класса Student можно получить его адрес проживания из переменной address класса Address.
Но из экземпляра класса Address невозможно получить данные о студентах, проживающих по адресу, связанному с данным экземпляром класса.

Данная связь называется однонаправленной (Unidirectional).

Для дальнейшего понимания отношений определим концепцию Родительской (Parent) и Дочерней (Child) таблиц.

В случае отношения Один-ко-Многим, дочерней называется таблица, содержащая внешний ключ.
В данном примере это таблица студентов, а внешний ключ - ссылка на таблицу адресов.
Проще говоря, дочерней таблицей при отношении Один-ко-Многим, является таблица, отражающая сущности "Многих"
Для реализации однонаправленной (Unidirectional) связи Один-ко-Многим достаточно использования аннотации @ManyToOne в объекте, соответствующему дочерней таблице в БД.
В нашем примере, в классе Student:

  1.     @ManyToOne
  2.     public Address getAddress() {  
  3.         return address;  
  4.     }  

Использование данной аннотации необходимо для создания Hibernate необходимого внешнего ключа в дочерней таблице Student.

Дополнительно эта аннотация может содержать параметры, описывающий поведение БД при удалении и/или вставке значений в связанные поля, например:


  1.     @ManyToOne(cascade = CascadeType.ALL)
  2.     public Address getAddress() {  
  3.         return address;  
  4.     }  




Если прикладная реализация требует получения не только адреса проживания каждого студента, но и всех студентов, проживающих по определенному адресу, то используется двунаправленная связь.

Для обозначения двунаправленной (Bidirectional) связи в Hibernate определена вторая аннотация: @OneToMany, в дополнение к аннотации @ManyToOne.

При отношении Один-ко-Многим для объекта, соответствующего дочерней таблице БД (со стороны "Многие"), используется аннотация @ManyToOne для соответствующего геттера.
А для объекта, соответствующего родительской таблице БД (со стороны "Один"), - аннотация @OneToMany для соответствующего геттера.
Для запоминания: на стороне "Многие" аннотация @ManyToOne,
а на стороне "Один" - @OneToMany
В случае двунаправленной (Bidirectional) связи необходимо дополнительно создать переменную родительского класса, которая позволит хранить коллекцию объектов дочернего класса. А так же связать геттер этой переменной с переменной дочернего класса, хранящую родительский объект, при помощью аннотации @OneToMany(mappedBy="address").
(где "address" - это имя переменной дочернего класса, отмеченная аннотацией @ManyToOne в данной связи)

  1. import javax.persistence.Entity;  
  2. import javax.persistence.GeneratedValue;  
  3. import javax.persistence.GenerationType;  
  4. import javax.persistence.Id;  
  5.   
  6. @Entity  
  7. public class Address {  

  8.     private Long id;  
  9.     private String address;  

  10.     private Set<Student> studentSet;  
  11.       
  12.     @Id  
  13.     @GeneratedValue(strategy=GenerationType.AUTO)  
  14.     public Long getId() {  
  15.         return id;  
  16.     }  

  17.     public void setId(Long id) {  
  18.         this.id = id;  
  19.     }  

  20.     public String getAddress() {  
  21.         return address;  
  22.     }  

  23.     public void setAddress(String address) {  
  24.         this.address = address;  
  25.     }  
  26.       
  27.     @OneToMany(cascade=CascadeType.ALL, mappedBy="address" 
  28.     public Set<Student> getStudentSet()  
  29.         return studentSet;  
  30.      

  31.     public void setStudentSet(Set<Student> studentSet) {  
  32.         this.studentSet = studentSet;  
  33.     }  
  34. }  

IntelliJ IDEA не загружаются архитипы Maven

При создании нового проекта Maven не загружаются доступные архитипы (Archetype):
enter image description here

В настройках (Default Settings) ветка "Build, Execution, Deployment" -> "Build Tools" -> "Maven" -> "Importing" в поле "VM option for importer" установить значение -Xmx1024m

Ошибки Glassfish

  1. При сохранении hibernate.cfg.xml файла в логе сервера приложений Glassfish появляется следующее предупреждение:
    Warning:   Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
    В редакторе реестра Windows (regedit) необходимо создать раздел "Key" в ветке HKEY_LOCAL_MACHINE\Software\JavaSoft (в Windows 10 - HKEY_LOCAL_MACHINE\Software\WOW6432Node\JavaSoft)
  2.