Cześć. Mam trzy tabele w bazie danych oraz trzy odpowiadające im modele klas.
Client.java
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "client")
public class Client {
@NotBlank
@NotNull
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private Long id;
@NotBlank
@Column(nullable = false)
private String name;
@Column(nullable = false, name = "is_company")
private Boolean isCompany;
@Column(length = 10, name = "reg_no")
private String regNo;
@Column(length = 10, name = "vat_id")
private String vatId;
@Column
private Set<Contact> contacts = new HashSet<>();
@Column(length = 100)
private Address address;
@Column
private Set<Address> shippingAddresses = new HashSet<>();
}
Contact.java
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "contact")
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
Long id;
@NotBlank
@Column(nullable = false)
String name;
@Column(length = 10)
String phone;
@Column(length = 30)
String email;
@Column(length = 10)
String fax;
}
Address.java
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "address")
public class Address {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
Long id;
@Column(nullable = false, length = 50)
String street;
String zip;
String state;
@Column(nullable = false)
String city;
@Column(nullable = false)
String country;
}
**application.properties
**
spring.thymeleaf.cache = false
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost/task?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false
spring.datasource.username = root
spring.datasource.password = root
# Configure Hibernate DDL mode: create / update
spring.jpa.properties.hibernate.hbm2ddl.auto = create
Teraz mam kilka pytań:
- Klasa Client.java robi problem (Unable to build Hibernate SessionFactory):
2018-01-18 1338.569 WARN 3524 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
2018-01-18 1338.574 INFO 3524 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-01-18 1338.587 INFO 3524 --- [ restartedMain] utoConfigurationReportLoggingInitializer :Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-01-18 1338.595 ERROR 3524 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failedorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Jeśli zakomentuję tę klasę to wszystko jest OK i aplikacja buduje się, w czym problem? Hibernate działa poprawnie bo z klasy Address.java mogę wyświetlać dane w Thymeleaf z bazy. Do bazy też wstawiają mi się dane z pliku w resources więc tutaj jest OK.
-
W jaki sposób mogę połączyć te trzy tabele w relacjach jeden do jednego po id (chyba że użyć jeden do wielu bo w sumie przy relacji w bazie jeden do jednego wynik będzie taki sam)? Starałem się to robić adnotacją @OneToOne jednak mimo różnych prób nie udało się to. Mogę połączyć tabelę address z tabelą client po id a tabelę client z tabelą contact również pod id? Czy potrzebuję jakichś dodatkowych id i tak nie można zrobić?
-
Czy typ Set<Address> i Set<Contact> w Client.java normalnie zostaną zmapowane przez Hibernate jak każda inna zmienna np typu String czy trzeba tu wykonywać jakąś operację dodatkowo?
-
Zrobiłem sobie interfejs ClientRepository który rozszerza JpaRepository<Client, Long>. Czy teraz wykonując jakieś metody CRUD operację będą wykonywały się na wszystkich tabelach bo zadba o to Hibernate (dzięki połączeniu danych z tabel wg punktu 2)?