h2 database unit test across multiple schema - database

I am trying to use unit test along with h2 database. My application uses MSSQL database. And below are the 2 table that am using in my application:
SchemaA.dbo.Table1<br>
SchemaB.dbo.table2<br>
#Entity<br>
#Table(name="SchemaB..table")<br>
Class A <br>
{
private Long id;
............
}
I am trying to write unit test to test the persistance of the above class. But h2 database does not recognise this tablename syntax:
SchemaB..table
Note : the 2 dots between schema name and table name.
Any suggestion would be greatly appreciated.

You may want to use the schema attribute of the Table JPA annotation.
For example:
#Entity(name = "Foo")
#Table(name = "TABLE_FOO", schema = "bar")
If you have a single data source, which connects to your h2 with user A. In order to access schema 'bar', you may want to tell h2 to automatically create schema 'bar' on connect.
jdbc:h2:mem:play;MODE=MySQL;INIT=RUNSCRIPT FROM 'test/init.sql'
The final part of the JDBC URL test/init.sql points to a sql file with the following content.
CREATE SCHEMA IF NOT EXISTS bar
H2 will execute the sql and create the schema on connect.
I've created a demo project at github.
The project has an init.sql file that creates 2 schema, foo and bar.
2 model classes foo.A and bar.B that use #Entity(schema="foo", name="A") to specify schema accordingly. see app/models.
The test case uses play framework therefore the built-in evolution tool can be applied every time test cases are executed. But it should be fine to use setUp method to apply your own sql script before executing test cases. Please see test folder for the sample test case. (it's actually scalaTest but it basically has the same idea as junit)

Related

Using a table from another database

When using EF core 6, I'd like to mark one table as coming from another database in SQL Server. It looks like the annotation allows specifying the schema, so I can do:
[Table("PRODUCTS", Schema = "dbo")]
But how I need to go one level lower. Unfortunately this:
[Table("PRODUCTS", Schema = "Drugs.dbo")]
results in [Drugs.dbo].[PRODUCTS] in the query, so I can't work around it that way.
How can I specify the database for that model without a separate database connection? I need to use tables from 2 catalogs in a single query. (Without any database-side changes)

Access a SQL Server 2008 View From Grails

We have a Grails project that needs to pull data from a SQL Server 2008 view. We just need to do a basic select from the view.
Is there a config setting for views such that we can map a domain class to the view?
Or should we use raw SQL like:
db.rows("SELECT foo, bar FROM my_view")
You can use SQL, e.g. with groovy.sql.Sql as suggested in the other similar question's answer, but it's also possible in a domain class. If you create a domain class (use any sensible name) and specify its table name as the name of the view, you can select from it. You'll have problems creating and updating of course, but if you only want to read then it'll be fine:
class SomeDomainClass {
String foo
Integer bar
static mapping = {
table 'my_view'
}
}
If you name the class MyView then mapping isn't needed since the naming convention applies, but this would be a bad name for the class since using it isn't related to the fact that it's backed by a view.
Note that you'll also have problems when using dbCreate set to "create", "create-drop", or "update" since Hibernate will try to create the table, but it shouldn't cause any real problem and just display an ignorable error like "could not create table 'my_view' since it already exists". And once you move to using database migrations this won't be a problem at all.

Oracle + dbunit throws AmbiguousTableNameException

I'm using DBUnit to populate the database so that its content is a known content during testing.
The db schema I'm working on is in an Oracle 11g instance in which they reside other db schemas. In some of these schemas has been defined a table to which has been associated with a public synonym and on which have been given the rights to select.
When I run the xml that defines how the database must be populated, also if the xml file doesn't contain the table defined in several schemas, DBUnit throws the AmbiguousTableNameException exception on that table.
I found that there are 3 solutions to solve this behavior:
Use a database connection credential that has access to only one
database schema.
Specify a schema name to the DatabaseConnection or
DatabaseDataSourceConnection constructor.
Enable the qualified table name support (see How-to documentation).
In my case, I can only apply the solution 1, but even if I adopt it, I got the same exception.
The table that gives me problems is defined in 3 schemas and I don't have the opportunity to act on it in any way.
Please, someone could help me?
I found the solution: I specified the schema in the name of the tables and I have set to true the property http://www.dbunit.org/features/qualifiedTableNames (corresponding to org.dbunit.database.FEATURE_QUALIFIED_TABLE_NAMES).
By this way, my xml code to populate tables look like:
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<SCHEMA.TABLE ID_FIELD="1" />
</dataset>
where SCHEMA is the schema name, TABLE is the table name.
To se the property I've used the following code:
DatabaseConfig dBConfig = dBConn.getConfig(); // dBConn is a IDatabaseConnection
dBConfig.setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
In my case,
I granted dba role to user, thus dbunit throw AmbiguousTableNameException.
After I revoke dba role to user, I solve that problem.
SQL> revoke dba from username;
I had the same AmbiguousTableNameException while executing Dbunits aginst Oracle DB. It was working fine and started throwing error one day.
Rootcause: while calling a stored procedure, it got modified by mistake to lower case. When changed to upper case it stared working.
I could solve this also by setting the shema name to IDatabaseTester like iDatabaseTester.setSchema("SCHEMANAMEINCAPS")
Thanks
Smitha
I was using SpringJDBC along with MySQL Connector (v8.0.17). Following the 2 steps explained in this answer alone did not help.
First I had to set the schema on the spring datasource.
Then I also had to set a property "databaseTerm" to "schema"
by default it is set to "catalogue" as explained here.
We must set this property because (in Spring's implementation of javax.sql.DataSource) if it's not set (i.e. defaulted to "catalogue") then the connection returned by dataSource.getConnection() will not have the schema set on it even if we had set it on the dataSource.
#Bean
public DriverManagerDataSource cloudmcDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("<driver>");
dataSource.setUrl("<url>");
dataSource.setUsername("<uname>");
dataSource.setPassword("<password>");
dataSource.setSchema("<schema_name>");
Properties props = new Properties();
// the following key-value pair are constants; must be set as is
props.setProperty("databaseTerm", "schema");
dataSource.setConnectionProperties(props);
return dataSource;
}
Don't forget to make the changes explained in answer here.

DBunit can't find tables defined on dataset

I have a dataset (defined in xml) and i am using PostGreSQL, POJOs annotated with JPA, and DbUnit with Junit for tests.
When the test runs, it creates the tables and sequences in the database, but when it starts to read the dataset (xml) with the table definitions and columns, it fires the following error
org.dbunit.dataset.NoSuchTableException "nameoftable" I tried to put the name of the table with all caps and normal caps, and it won't work. The table was created in the public schema, and then i tried to define in the xml the table as public."nameoftable" but it also won't work.... any ideas?
I tried to run this tests with DUnit in the following versions: 2.2.2, 2.3.0, and 2.4.5.
Thanks.
With DBUnit you can either use a specific schema to test against, or a full database (with potentially multiple schema). If you use the latter you need to specify the schema in the dataset when importing/exporting or it can get itself confused; in PostgreSQL at least, I've not tried it with anything else.
To enforce this add the following code in:
if (strSchema == null || strSchema.isEmpty()) {
conn = new DatabaseConnection(jdbcConnection);
conn.getConfig().setProperty(
"http://www.dbunit.org/features/qualifiedTableNames", true);
}
else
conn = new DatabaseConnection(jdbcConnection, strSchema);
The important bit is the setting of the property; the rest is something I use to make the connection relevant to the DB or schema (based upon a schema name extracted from the hibernate config XML).

RIA Services - call a stored procedure

I am using RIA Services with Silverlight and Entity Framework. I want to call a stored procedure and map the results to a datagrid. What is the best way to do this? The output of the stored procedure doesn't map to any table design.
I found the following article -
http://blogs.msdn.com/b/tom/archive/2009/05/07/silverlight-ria-calling-stored-procedures-that-don-t-return-tables.aspx
However, it doesn't work for me - I get an error saying that the result complex set does not have a primary key defined. I can't see how to define this in code.
Anyway, I'm open to any and all solutions.
I found the following excellent step-by-step guide at this site -
http://betaforums.silverlight.net/forums/p/218383/521023.aspx
1) Add a ADO Entity Data Model to your Web project; Select generate from database option; Select your Database instance to connect to.
2) Choose your DB object to import to the Model. You can expand Table node to select any table you want to import to the Model. Expand Stored Procedure node to select your Stored Precedure as well. Click Finish to finish the import.
3) Right click the DB model designer to select Add/Function Import. Give the function a name (same name as your SP would be fine) and select the Stored Procedure you want to map. If your SP returns only one field, you can map the return result to a collection of scalars. If your SP returns more than one field, you could either map the return result to a collection or Entity (if all the field are from a single table) or a collection of Complex types.
If you want to use Complex type, you can click Get Column button to get all the columns for your SP. Then click Create new Complex type button to create this Complex type.
4) Add a Domain Service class to the Web project. Select the DataModel you just created as the DataContext of this Service. Select all the entitis you want expose to the client. The service functions should be generated for those entities.
5) You may not see the Complex type in the Entity list. You have to manully add a query function for your SP in your Service:
Say your SP is called SP1, the Complex type you generated is called SP1_Result.
Add the following code in your Domain Service class:
public IQueryable<SP1_Result> SP1()
{
return this.ObjectContext.SP1().AsQueryable();
}
Now you can compile your project. You might get an error like this: "SP1_Result does not have a Key" (if you not on RIA service SP1 beta). If you do, you need to do the following in the service metadata file:
Added a SP1_Result metadata class and tagged the Key field:
[MetadataTypeAttribute(typeof(SP1_Result.SP1_ResultMetadata))]
public partial class SP1_Result
{
internal sealed class SP1_ResultMetadata
{
[Key]
public int MyId; // Change MyId to the ID field of your SP_Result
}
}
6) Compile your solution. Now you have SP1_Result exposed to the client. Check the generated file, you should see SP1_Result is generated as an Entity class. Now you can access DomainContext.SP1Query and DomainContext.SP1_Results in your Silverlight code. You can treat it as you do with any other Entity(the entity mapped to a table) class.
Well, I figured out how to do it, though it's a bit messy. You need to create a metadata class for the result set in the domain metadata file. After that, RIA will treat it essentially like it does an entity.
Full details can be found here - http://leeontech.wordpress.com/2010/05/24/ria-services-and-storedprocedures/

Resources