Java 11
Try to use Hibernate
Here migration sql:
create table client ( id bigserial primary key, name varchar(255), phone varchar(255) ); create sequence clientId start 1 NO MAXVALUE; create table address_data_set ( id bigserial primary key, street varchar(255) not null, client_id bigint not null references client(id) ); create sequence addressId start 1 NO MAXVALUE;
Here entities:
import javax.persistence.*; import java.util.ArrayList; import java.util.List; import static javax.persistence.GenerationType.SEQUENCE; @Entity @Table(name = "client") public class Client { @Id @GeneratedValue(strategy = SEQUENCE, generator="clientId_generator") @SequenceGenerator(name = "clientId_generator", sequenceName = "clientId", allocationSize = 1) private Long id; @Column(name = "name") private String name; @Column(name = "addresses") @OneToMany(mappedBy = "client", cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<AddressDataSet> addresses = new ArrayList<>(); @Column(name = "phone") private String phone; }
And one more
import javax.persistence.*; import static javax.persistence.GenerationType.SEQUENCE; @Entity @Table(name = "address_data_set") public class AddressDataSet { @Id @GeneratedValue(strategy = SEQUENCE, generator="addressId_generator") @SequenceGenerator(name = "addressId_generator", sequenceName = "addressId", allocationSize = 1) private Long id; @Column(name = "street") private String street; @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "client_id", nullable = false) private Client client; }
And try run like this:
private Main() { flywayMigrations(); var configuration = new Configuration() .setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL10Dialect") .setProperty("hibernate.connection.url", URL) .setProperty("hibernate.connection.username", USER) .setProperty("hibernate.connection.password", PASSWORD) .setProperty("hibernate.show_sql", "true") .setProperty("hibernate.hbm2ddl.auto", "validate") .setProperty("hibernate.generate_statistics", "true"); var serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()).build(); var metadata = new MetadataSources(serviceRegistry) .addAnnotatedClass(Client.class) .getMetadataBuilder() .build(); sessionFactory = metadata.getSessionFactoryBuilder().build(); } private void flywayMigrations() { logger.info("db migration started..."); var flyway = Flyway.configure() .dataSource(URL, USER, PASSWORD) .locations("classpath:/db/migration") .load(); flyway.migrate(); logger.info("db migration finished."); logger.info("***"); }
But I get error:
2022-01-13 19:53:45.784 INFO hw10.Main - db migration started... 2022-01-13 19:53:45.853 INFO o.f.c.i.license.VersionPrinter - Flyway Community Edition 7.1.1 by Redgate 2022-01-13 19:53:45.984 INFO o.f.c.i.database.base.DatabaseType - Database: jdbc:postgresql://localhost:5430/hw10 (PostgreSQL 12.9) 2022-01-13 19:53:46.050 INFO o.f.core.internal.command.DbValidate - Successfully validated 2 migrations (execution time 00:00.036s) 2022-01-13 19:53:46.063 INFO o.f.core.internal.command.DbMigrate - Current version of schema "public": 11 2022-01-13 19:53:46.064 INFO o.f.core.internal.command.DbMigrate - Schema "public" is up to date. No migration necessary. 2022-01-13 19:53:46.066 INFO hw10.Main - db migration finished. 2022-01-13 19:53:46.066 INFO hw10.Main - *** Exception in thread "main" org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: hw10.model.Client.addresses[hw10.model.AddressDataSet] at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1351) at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:874) at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:799) at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:53) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1693) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1661) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86) at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:479) at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
Advertisement
Answer
The problem is in this block:
@Column(name = "addresses") @OneToMany(mappedBy = "client", cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<AddressDataSet> addresses = new ArrayList<>();
You either use @Column
or a@One/ManyToOne/Many
relation. You cannot use both. The first one is for mapping primitive data types. The other one is for entities relations. Remove @Column
and you should be good to go.
Update
You added Client
as annotated class, but not AddressDataSet
. Add it just under the addAnnotatedClass(Client.class)
:
var metadata = new MetadataSources(serviceRegistry) .addAnnotatedClass(Client.class) .addAnnotatedClass(AddressDataSet.class) .getMetadataBuilder() .build();