Unitils and DBMaintainer - how to make them work w

2019-01-26 23:23发布

问题:

I am working on a new Oracle ADF project, that is using Oragle 10g Database, and I am using Unitils and DBMaintainer in our project for:

  • updating the db structure
  • unittesting
  • read in seed data
  • read in test data
  • List item

In our project, we have 2 schemas, and 2 db users that have privilegies to connect to these schemas. I have them in a folder structure with incremental names and I am using the @convention for script naming.

001_@schemaA_name.sql 
002_@schemaB_name.sql 
003_@schemaA_name.sql 

This works fine with ant and DBMaintainer update task, and I supply the multiple user names by configuring extra elements for the ant task.

<target name="create" depends="users-drop, users-create" description="This tasks ... ">
    <updateDatabase scriptLocations="${dbscript.maintainer.dir}" autoCreateDbMaintainScriptsTable="true">
       <database name="${db.user.dans}" driverClassName="${driver}" userName="${db.user.dans}" password="${db.user.dans.pwd}" url="${db.url.full}" schemaNames="${db.user.dans}" />
        <database name="idp" driverClassName="${driver}" userName="${db.user.idp}"
            password="${db.user.idp.pwd}" url="${db.url.full}" schemaNames="${db.user.idp}" />
    </updateDatabase>
</target>

However, I cant figure out, how to make the DBMaintainer update task create the xsd schemas from my db schemas?

So, I decided to use Unitils, since its update creates xsd schemas. I haven't found any description or documentation for the Unitils ant tasks - can anyone give some hints? For the time being I have figured out to run Unitils by creating a Junit test, with @Dataset annotation. I can make it work with one schema, and one db user. But I am out of ideas how to make it work with multiple users?

Here is the unitils-local.properties setup I have:

database.url=jdbc\:oracle\:thin\:@localhost\:1521\:vipu
database.schemaNames=a,b
database.userName=a
database.password=a1

Can any of you guys give me a tip, how to make Unitils work with the second user/schema ?? I will be extremely gratefull for your help!

回答1:

eventually I found a way to inject any unitil.properties of your choice --- by instantiating Unitils yourself!

You need a method that is evoked @BeforeClass, in which you perform something like the following:

@BeforeClass
public void initializeUnitils {
    Properties properties;
    ...
    // load properties file/values depending on various conditions
    ...
    Unitils unitils = new Unitils();
    unitils.init(properties);
    Unitils.setInstance( unitils );     
}

I choose the properties file depending on which hibernate configuration is loaded (via @HibernateSessionFactory), but there should be other options as well



回答2:

I have figure out how to make dbmaintain and unitils work together on multi-database-user support, but the solution is a pure ant hack.

  1. I have set up the configuration for dbmaintain, using multi-database-user support.
  2. I have made a unitils-local.properties file with token keys for replacement.
  3. The init target of my ant script is generating a new unitils-local.properties file, by replacing tokens for username/password/schema with values that are correct for the target envirnonment, and then copies it to the users home directory.
  4. I have sorted the tests into folders, that are prefixed with the schema name
  5. When unitils is invoked, it picks up the unitils-local.properties file just created by the ant script, and does its magic.

Its far from pretty, but it works.



回答3:

Check out this link: http://www.dbmaintain.org/tutorial.html#From_Java_code

Specifically you may need to do something like:

databases.names=admin,user,read
database.driverClassName=oracle.jdbc.driver.OracleDriver
database.url=jdbc:oracle:thin://mydb:1521:MYDB
database.admin.username=admin
database.admin.password=adminpwd
database.admin.schemaNames=admin
database.user.userName=user
database.user.password=userpwd
database.user.schemaNames=user
database.read.userName=read
database.read.password=readpwd
database.read.schemaNames=read

Also this link may be helpful: http://www.dbmaintain.org/tutorial.html#Multi-database__user_support



回答4:

I followed Ryan suggestion. I noticed couple changes when I debugged UnitilsDB.

Following is my running unitils-local.properties:

database.names=db1,db2
database.driverClassName.db1=oracle.jdbc.driver.OracleDriver
database.url.db1=jdbc:oracle:thin:@db1d.company.com:123:db1d
database.userName.db1=user
database.password.db1=password
database.dialect.db1=oracle
database.schemaNames.db1=user_admin

database.driverClassName.db2=oracle.jdbc.driver.OracleDriver
database.url.db2=jdbc:oracle:thin:@db2s.company.com:456:db2s
database.userName.db2=user
database.password.db2=password
database.dialect.db2=oracle

Make sure to use @ConfigurationProperties(prefix = "database.db1") to connecto to particular database in your test case:

@RunWith(UnitilsJUnit4TestClassRunner.class)
@ConfigurationProperties(prefix = "database.db1")
@Transactional
@DataSet
public class MyDAOTest {

..

}