How would I create two tables in a single database in dropwizard?
In my run method I have:
public void run(HelloWorldConfiguration configuration, Environment environment) {
final PersonDAO dao = new PersonDAO(hibernateBundle.getSessionFactory());
final LADAO dao2 = new LADAO(hibernateBundle.getSessionFactory());
environment.jersey().register(new ProtectedResource());
environment.jersey().register(new PeopleResource(dao));
environment.jersey().register(new PersonResource(dao));
environment.jersey().register(new LAResource(dao2));}
Tables are created in your migrations.xml file
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
<changeSet id="1" author="people">
<!-- first table created -->
<createTable tableName="table1">
<column name="jobTitle" type="varchar(255)"/>
</createTable>
<!-- second table created -->
<createTable tableName="table2">
<column name="whatever" type="varchar(255)"/>
</createTable>
</changeSet>
</databaseChangeLog>
Then use the 'db migrate' command to run the migration:
java -jar hello-world.jar db migrate helloworld.yml
Related
I am taking an existing Java application and working on updating it from Hibernate 3 where we used hbm.xml files for Entity Mappings. We are now using Hibernate 5.5.5.Final and the code compiles with ehcache, but now I get an error with the code when starting to run it.
I should start off that one of the Hibernate properties is:
validate
The error message I am getting now is:
org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [my_db_dev.Project_myTemplateInfos]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:121)
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:200)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:327)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
I would love to completely remove all the hbm.xml files and replace with them with Entity Mapping POJO's with annotations, however, that is not an option right now. The existing application has this different object model that goes throughout, so I don't want to mess with that right now. That will be in the next phase.
According to the error I am missing a table named 'Project_myTemplateInfos' and there is no table with this name. Instead, there is a table named 'Project' and the hbm.xml file for this is as follows.
<hibernate-mapping package="com.myApp.server.model">
<class name="Project" table="project" dynamic-update="true">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" not-null="true"/>
<property name="displayCity" not-null="true"/>
<list name="myTemplateInfos" cascade="all, delete-orphan" lazy="false" >
<key column="projectId" not-null="false" />
<list-index column="listIndex" />
<composite-element class="com.myApp.server.model.MyTemplateInfo" >
<property name="name" not-null="false" />
<property name="frequency" not-null="false" />
</composite-element>
</list>
</class>
</hibernate-mapping>
As you can see 'myTemplateInfos' is a List within the Project table. After the POJO is created, it looks like something like this.
#ModelBean(IProject.class)
#PermissionIdentifier("project")
public class Project extends ModelObject implements Serializable, IProject {
private Long id;
private String displayCity = "";
private List<IMyTemplateInfo> myTemplateInfos = Lists.newArrayList();
// getters and setters
// hashcode and equals
}
Next we do have another table in the database that is called 'myTemplateInfos' and we do have an hbm xml file for that table as follows ... actually we do not have an hbm xml file for this, so maybe that is the issue. I am going to create a hbm xml file for this and see if that solves the problem.
We do have a POJO for this object 'MyTemplateInfo' though.
If I simply remove his List from the hbm mapping and the Project object, the problem goes away of course, but there is another Set in the hbm.xml file which would give me the same problem, but with a new missing table.
The question becomes how to fix this error message. Is the problem within the hbm xml file for 'Project', or is it in the Project POJO, or the fact that an hbm file does not exist for the 'MyTemplateInfo'?
The solution to this was to fix the hbm xml mapping. Since I haven't had to do this in over 15 years, I am very rusty with it. I can't tell you how happy I was back then to switch to Java POJO's for Hibernate Entity classes with Annotations. But now, unfortunately, I am back having to deal with these xml files again.
The table I had 'mycommunitytemplateinfos' I created a new hbm xml file for it as follows, and put this in the hibernate.cfg.xml file before the other hbm xml mapping.
<hibernate-mapping package="com.myapp.server.model">
<class name="MyTemplateInfo" table="mytemplateinfos">
<id name="id" column="projectId">
<generator class="native"/>
</id>
<property name="name" not-null="false" />
<property name="frequency" not-null="false" />
</class>
</hibernate-mapping>
The mapping between this and the actual class is fine as I have tested this out. I put the hbm file in the hibernate.cfg.xml file before the Project.hbm.xml file and modified the Project.hbm.xml with a one-to-many tag as follows:
<list name="myTemplateInfos" cascade="all, delete-orphan" lazy="false" >
<key column="projectId" not-null="false" />
<list-index column="listIndex" />
<one-to-many class="com.myApp.server.model.MyTemplateInfo" />
</list>
And this seemed to work. I had to do something like this a few times until I got the mapping right. In this day of age, there isn't a lot of information about hbm xml files. Hibernate 5 does use these, but I understand that the preferred way is annotated Java POJO's. Unfortunately, I am stuck in a situation where I can't do that yet.
Why When i run my project which is with Java 8, Spring Boot, Liquibase and Postgresql, i do not see any new table in my postgres database?
I installed PostgreSQL 11.6,
This is changelog-master.xml:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<include file="/db/changelog/changes/create-table-changelog-1.xml"/>
</databaseChangeLog>
This is create-table-changelog-1.xml
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet author="admin" id="1">
<createTable tableName="person11">
<column autoIncrement="true" name="id" type="INT">
<constraints primaryKey="true"/>
</column>
<column name="name" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="address" type="VARCHAR(255)"/>
</createTable>
<!-- <rollback>
<dropTable tableName="person11"/>
</rollback>-->
</changeSet>
</databaseChangeLog>
This is application.properties:
spring.liquibase.changeLog = classpath:/db/changelog/changelog-master.xml
spring.datasource.url= jdbc:postgresql://localhost:5432/
spring.datasource.username=postgres
spring.datasource.password=postgres
This is pom.xml file:
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.8.9</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.14</version>
<scope>compile</scope>
</dependency>
I think you should also specify the database name at the end of your datasource url, like this jdbc:postgresql://localhost:5432/DB_NAME
You must ensure to have an implementation of JPA in order for JPA to interact with the database. I usually use the dependency spring-boot-starter-data-jpa which comes with hibernate, add the dependency in the pom file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
You may need to add the following dependency in your pom.xml as well:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
And if you are using Spring Boot 2, then you would also need to change the property name to spring.liquibase.change-log in your application.properties file.
Thank you all for your answers,
When i followed this link, my issue is solved. In this link there is an example for integrating Spring-Boot, JPA and Liquibase:
https://auth0.com/blog/integrating-spring-data-jpa-postgresql-liquibase/
I keep table schema in this file tableaddress.orm.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.1"
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<entity class="Address">
<attributes>
<basic name="city" attribute-type="String" />
<basic name="country" attribute-type="int" />
<basic name="province" attribute-type="double" />
<basic name="postalCode" attribute-type="boolean">
</basic>
<basic name="street" attribute-type="String" />
</attributes>
</entity>
</entity-mappings>
Here is how I tried to create table using Hibernate
public class App
{
public static void main( String[] args )
{
Properties prop= new Properties();
prop.setProperty("hibernate.connection.url", "jdbc:mariadb:......");
prop.setProperty("dialect", "org.hibernate.dialect.MariaDB53Dialect");
prop.setProperty("hibernate.connection.username", "user");
prop.setProperty("hibernate.connection.password", "password");
prop.setProperty("hibernate.connection.driver_class", "org.mariadb.jdbc.Driver");
SessionFactory sessionFactory = new Configuration()
.addResource("tableaddress.orm.xml").addProperties(prop).buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.getTransaction().commit();
session.close();
}
}
It should work, there is no compile errors, but for some reason the table is not created
Error java.lang.NoClassDefFoundError: javax/transaction/SystemException
This is probably due to bug/feature in Hibernate.
The javax.transaction was removed from Hibernate (well, marked as "provided") in 5.0.4, but it was brought back in 5.0.7 (see https://hibernate.atlassian.net/browse/HHH-10307 :
"JTA no longer transitively provided (HHH-10178) causes problems for
apps not using JTA"
)
So assuming you are using 5.04, 5.0.5 or 5.0.6, your choices are to either upgrade Hibernate, or to add the following dependency :
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
I'm trying to implement Axon app using JPA Event Store and mysql database. Hibernate is automatically generating all the tables and it works OK so far.
My question is - can I replace hibernate_sequence mysql table for AUTO_INCREMENT columns in Mysql. I guess in order to do this I would need to modify source code of Axon, since I cannot find other configurable way to modify #Id annotation for Domain event #Entity or other entitites?
UPDATE
OK, i managed to do it by placing new file in src\main\resources\META-INF\orm.xml with following code:
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0">
<mapped-superclass class="org.axonframework.eventhandling.AbstractSequencedDomainEventEntry" access="FIELD">
<attributes>
<id name="globalIndex">
<generated-value strategy="IDENTITY"/>
</id>
</attributes>
</mapped-superclass>
<entity class="org.axonframework.modelling.saga.repository.jpa.AssociationValueEntry" access="FIELD">
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
</attributes>
</entity>
</entity-mappings>
You could make this adjustment through code, that's true.
It is however more straightforward to specify an orm.xml file in your project which for some tables (the domain_event_entry table in your scenario I assume) can adjust certain columns.
In there you should be able to adjust the sequence generator to what you desire it to be.
Hope this helps!
I have the following class:
package lt.vic.valdos.domain.valda;
public class Valda implements java.io.Serializable {
private long id;
private Long valdosKodas;
public long getId() {
return id;
}
public Long getValdosKodas() {
return valdosKodas;
}
}
and the following orm.xml:
<?xml version="1.0"?>
<entity-mappings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_1.xsd"
version="2.1">
<entity class="lt.vic.valdos.domain.valda.Valda">
<table name="VALDOS" schema="VLD" />
<attributes>
<id name="id" />
<basic name="id">
<column name="vld_id" />
<return-insert return-only="true" />
</basic>
<basic name="valdosKodas">
<column name="valdos_kodas" />
</basic>
</attributes>
</entity>
</entity-mappings>
When I deploy this in glassfish, i get the following error:
Exception [EclipseLink-7215] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Could not load the field named [id] on the class [class lt.vic.valdos.domain.valda.Valda]. Ensure there is a corresponding field with that name defined on the class.
The class is in a jar that is included into a web application as a maven dependency. The orm.xml is in /WEB-INF/classes/META-INF of the web application.
What am I doing wrong?
Figured this one out myself. For some reason EclipseLink requires a setter on a class. Once I add private setters everything seems fine. Why the setters are needed (mapping accessors should default to FIELD) remains a mystery but it is not that important for me. Adding access="FIELD" to all entity attributes also fixes the problem without the setters.
You should be specifying the id as generated using the IDENTITY strategy:
<id name="id">
<column name="vld_id"/>
<generated-value strategy="IDENTITY"/>
</id>
This strategy will automatically read the database provided id back into the new object upon successful commit. The EclipseLink returning statement functionality is only applicable to basic mappings because id is already covered by Identity ID generation.
I think you have to add the column description for the id column to your id element, instead of using an extra basic element. As in <id name="id"> <column name="vld_id" /> ... </id>, without an extra <basic name="id"> ....
From my own experience (some time ago now), it's probably easier to use annotations to define your mappings.