Is there a way to store an actual database scheme close to chagelogs? - spring-boot

I have configured the liquibase migration for my Spring Boot application. Now I have a chagelog folder with all changes and I'd like to have a file with current database scheme because it's convenient. Does liquibase have best practices for storing actual db scheme in Spring Boot project?

Your question is confusing. When you say "a file with current database scheme", are you referring to the actual database with data (such as a SQLite file) or a script to create the database initial state?
If what you want is the actual database, this is not a liquibase concern. You could certainly put the database file in the same folder as the scripts, but that would not make a lot of sense to me. The liquibase scripts should be considered part of your source code, the database is execution environment specific and probably belongs elsewhere.
If you want a script for the initial state, that is absolutely something you can do with liquibase. The command you want is generateChangeLog. This will analyse your existing database and generate a changelog to recreate it. You would then refer to it as the first changelog to execute in your scripts.
java -jar liquibase.jar
--classpath=sqlitejdbc-v<version>.jar
--driver=org.sqlite.JDBC
--url="jdbc:sqlite:exampledb.sqlite"
--changeLogFile=db.changelog.initial-state.xml
generateChangeLog
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<include file="db.changelog.initial-state.xml" />
<changeSet author="captain" id="diff1">
do some stuff
</changeset>
<changeSet author="captain" id="diff2">
do some more stuff
</changeset>
...

Related

Structure test scripts with liquibase to execute in order with normal scripts

we are using liquibase for migrating database in spring boot application. In resources we have main changelog file which includes other changelogs (1 per version).
We usually differentiate environments by liquibase's context attribute but new we need differentiate data which are only for integration tests, and don't want place it next to normal versioned scripts. Is possible place these integration tests scripts in test's scope of project and execute them in order with normal scripts?
For instance:
main changelog:
<include file="version-1.xml"/>
<include file="version-2.xml"/>
and version 1 sample:
<changeSet id="1ver_1" author="xxx">
<!-- creation of table foo_table -->
</changeSet>
<changeSet id="1ver_2" author="xxx">
<!-- adding column to table foo_table -->
</changeSet>
version 2 sample:
<changeSet id="2ver_1" author="xxx">
<!-- renaming table foo_table to bar_table -->
</changeSet>
I need that if scripts for integration tests will written after script 1ver_1 and will contains inserts, it will be ok if next will be executed 1ver_2 and 2ver_1.
So when db for instegration tests started, scripts will be executed in right order:
1ver_1
test_data for 1ver_1
1ver_2
2ver_1
what is best practice to do that?
I think you should change the way you keep your changesets. Have a look at Liquibase Best Practices.
So your master changelog should look like:
<include file="version-1.1.xml"/>
<include file="version-1.2.xml"/>
<include file="version-2.1xml"/>
If you do this, you can have dedicated master changelog file for integration test. Your integration test's changelog-master.xml will look like this:
<include file="version-1.1.xml"/>
<include file="test_data_version-1.1.xml"/>
<include file="version-1.2.xml"/>
<include file="version-2.1xml"/>
After that you just override property in integration tests:
liquibase.change-log=classpath:integration-liquibase-changeLog.xml
Also you should place integration-liquibase-changeLog.xml and all 'test_data_xx.xml' into integration test module resource or test resource (it depends on project structure). The main idea it should not be provided to production artifacts.

Spring schema folder & Spring XML namespaces

I am looking for how we should determine the symbol of a namespace in Spring bean XML definitions. I guess they are in the Spring schema folder, but I can't find it. For example, what are c:, p:, util:, .. in the XML bean configuration?
Where can I find the schema's for each namespace? For example, how do I know if I should use http://www.springframework.org/schema/p in xmlns:p="http://www.springframework.org/schema/p", where are the other namespaces and how can I find them?
You can choose the symbol (p, util, jee, beans, ...) by yourself. These are namespaces, and they work by adding the xmlns attribute like:
<beans xmlns:util="http://www.springframework.org/schema/util">
<!-- Content -->
</beans>
In this case we said that util: will be used by the util schema, so you'll have to use <util:properties> to access things from this namespace. But you could also have said xmlns:foobar="http://www.springframework.org/schema/util" in which case you could have used things like <foobar:properties>.
But you also need to provide the location of the XSD of that namespace by using xsi:schemaLocation:
<beans xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Content -->
</beans>
In this case the XSD for http://www.springframework.org/schema/util is available at http://www.springframework.org/schema/util/spring-util.xsd. The http://www.springframework.org/schema/util part is just a label and can be chosen as well. The only thing that has to match is the XSD schema.
For more information about XML namespaces, you should look at this question and its answers.
A list of common XML schema's with Spring can be found in their documentation (33. XML Schema-based configuration). However, these only list the core schemas. Some projects (like Spring Web Services, ...) have their own namespaces like:
http://www.springframework.org/schema/web-services/web-services.xsd
http://www.springframework.org/schema/oxm/spring-oxm.xsd
...
You can find the entire list by visiting the Index of /schema. However, like I mentioned, most of these are only used for specific Spring projects, don't just import them, read the specific documentation to find out what you need. The documentation about the constructor namespace (c:) can be found in 7. The IoC container.

Using values defined in Liquibase property file inside CDATA tag

Unfortunately we don't use Liquibase built-in tags at work and it's already too late to fix the existing changesets. Has anyone tried to pass parameters to queries wrapped in CDATA tag without modifying the Liquibase maven plugin? However, Adding a new maven build plugin is ok.
<changeSet id="XXXXX" author="Mehrad">
<sql>
<![CDATA[
DO SOMETHING USING THE PARAMETER..
]]>
</sql>
<rollback><sql><![CDATA[ do something else ]]></sql></rollback>
</changeSet>
Liquibase support changelog paramters which I think is what you are looking for. You should be able to use then in CDATA blocks, especially with the later (3.2.2+) versions of Liquibase.

spring src-resolve issue "Cannot resolve the name ...''

I'm stuck with a standalone java application I'm maintaining, I'm really new with Maven. I use the copy dependencies, package plugins in command line and everything it's ok, but then when I see the project in eclipse, it validates the project and it seems that there is a problem checking which .xsd version should take into account.
Description Resource Path Location Type src-resolve: Cannot resolve
the name 'beans:identifiedType' to a(n) 'type definition'
component. spring-jee-2.0.xsd
Description Resource Path Location Type src-resolve: Cannot resolve
the name 'beans:identifiedType' to a(n) 'type definition'
component. spring-jee-2.5.xsd
I'm using spring 2.5.6 and I cannot upgrade. I do not know if I have to set up something in my eclipse IDE.
My configuration file is like this:
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
Any ideas or suggestions? Is it something related with a problem in the project or with eclipse IDE?
Thanks in advance
I cannot reproduce your situation, but it seems to be related to this problem:
That's a feature of STS (trying to be clever and importing XSD from
project classpath it fails to find the spring core ones). Raise a JIRA
ticket there if you want to really solve the problem, but my
understanding is that it is a compromise - users who do not edit
custom XSDs are far more numerous than those that do, so it's better
to support the larger group.
You can work around it by adding the spring-beans-3.1.xsd to your XML
Catalog in Eclipse (look in Preferences). You probably only need to
specify a namespace id, but I always add the schema location to be on
the safe side. You probably need to extract the XSD from the spring
jar file because I don't think you can add a catalog entry from a jar.
So, try to add spring-beans-2.5.xsd to XML Catalog in Eclipse. Hope this helps.

avoid loading hbm files automatically

I have two databases (Oracle and SqlServer) and I have the same table (Province) in both. I'm using JPA with Hibernate and need to perform operations to any of those databases.
I have an hbm mapping file for each table but both refer to the same class (Province.java).
I've configured hibernate.Oracle.cfg.xml and hibernate.SqlServer.cfg.xml in order to declare the mappings appropriately for each DB.
I'm also using Spring.
Here's my problem. When the application loads (actually JUnit) it tries to load both hbm files throwing DuplicateMappingException because Province.java is twice. Moreover, if I only keep one hbm file and one hibernate config file it still throws DuplicateMappingException; BUT if I remove the mapping from the hibernate config file then it works (but I don't want this). This means that the hbm file is automatically loaded and it is then loaded again due to it is declared in the config file.
Is there a way I can avoid hbm files to be automatically loaded?
I was finally able to find the solution to this problem. I added <exclude-unlisted-classes>false</exclude-unlisted-classes> to both persistence units in persistence.xml file and it prevented the hbm files to be loaded automatically. I also had to place the mapping in both hibernate.Oracle.cfg.xml and hibernate.SqlServer.cfg.xml.

Resources