Auto creation of database tables using JDO - mysql

I am new to JDO and MySQL. In my project, i want that all entities should be converted in table automatically.
I had start using the JDO and defined properties like this,
javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.api.jdo.JDOPersistenceManagerFactory
datanucleus.autoCreateSchema=true
datanucleus.validateTables=false
datanucleus.validateConstraints=false
datanucleus.query.sql.allowAll = true
javax.jdo.option.ConnectionDriverName=com.mysql.jdbc.Driver
javax.jdo.option.ConnectionURL=jdbc:mysql://127.0.0.1:3306/db_name
javax.jdo.option.ConnectionUserName=user
javax.jdo.option.ConnectionPassword=123456
javax.jdo.option.Mapping=hsql
Sample entity:
#PersistenceCapable(identityType = IdentityType.APPLICATION, table = "heartbeat")
public class HeartBeat implements Serializable{
#PrimaryKey
#Column(length=128)
private String userId;
.......
}
Now, when i compile or run my application the tables are not being auto created. I am not sure which property i should use for auto creation of tables based on the entities created.
Please bear with my question as i am new to JDO and MySQL integration.
Thanks in advance.

For JDO, if you want to create the schema for "tables" during the persistence process you tell DataNucleus by using this property, datanucleus.schema.autoCreateTables.
To auto create "columns" use datanucleus.schema.autoCreateColumns, and for "constraints" use datanucleus.schema.autoCreateConstraints. Set the properties to true.
<property name="datanucleus.schema.autoCreateTables" value="true"/>
<property name="datanucleus.schema.autoCreateColumns" value="true"/>
<property name="datanucleus.schema.autoCreateConstraints" value="true"/>
Shortcut for the three, use datanucleus.schema.autoCreateAll and set to true.
<!-- shortcut for the three -->
<property name="datanucleus.schema.autoCreateAll" value="true"/>
You can check the documentations here http://www.datanucleus.org/products/accessplatform_4_1/jdo/schema.html
Defined your JDO properties like this;
datanucleus.schema.autoCreateTables=true
datanucleus.schema.autoCreateColumns=true
datanucleus.schema.autoCreateConstraints=true
or shortcut
datanucleus.schema.autoCreateAll=true

Related

Apache Ignite use table names instead of cachename in a query

i have an application made in java that queries a schema many times (about 1000) for each request made by the user.
This was initially designed in this way many years ago and currently the code refactor would be too risky for the complexity of the methods.
Anyway, in order to leverage the DB effort i thought to introduce an Ignite layer to cache the biggest part of the data queried that is basically static, so i would expect that many of those queries will be faster and not on the DB anymore.
I've configured ignite properly on the server to cache the tables I need, and everything's fine until I tried to query on DBEaver or Squirrel and i discovered that the name of the tables to query on the Ignite DB is what in the ignite configuration is called property name=cacheName".
I don't want to put the hands on the code to change the queries one by one, so i would assume there's a way to keep the queries as the same as those are on the Oracle DB.
Example
In oracle DB i have
<Schema_Name>.<Table_Name>
and my queries in the code are something like
"select * from <Table_Name> where x"
In Ignite schema instead i have
cacheName.<Table_Name>
so in order to query this my query should be transformed in something like
"select * from cacheName.<Table_Name> where x"
Seems like in Ignite the cacheName is considered as a Schema, the problem is that each single table has different schema in this way. Should I consider to refactor all the queries or is there a way to mantain the same query format?
my configuration is something like this
Taken from one table configuration
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="<TableName>Cache"/>
<property name="cacheMode" value="PARTITIONED"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="cacheStoreFactory">
<bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory">
<property name="dataSourceBean" value="dsOracle"/>
<property name="dialect">
<bean class="org.apache.ignite.cache.store.jdbc.dialect.OracleDialect">
</bean>
</property>
<property name="types">
<list>
<bean class="org.apache.ignite.cache.store.jdbc.JdbcType">
<property name="cacheName" value="<TableName>Cache"/>
<property name="keyType" value="package.obfuscated.key"/>
<property name="valueType" value="package.obfuscated.type"/>
<property name="databaseSchema" value="<DBSchemaName>"/>
<property name="databaseTable" value="<TableName>"/>
<property name="keyFields">
<list>
<bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
.
.
.
[list of table fields]
.
.
Thanks a lot
In your cache definition, you can set the SQL Schema:
var cacheConfiguration = new CacheConfiguration<PersonKey,Person>()
.setName("PERSON_CACHE")
.setSqlSchema("MY_SCHEMA")
.setCacheMode(CacheMode.PARTITIONED)
.setIndexedTypes(PersonKey.class, Person.class);
var cache = ignite.<PersonKey,Person>getOrCreateCache(cacheConfiguration);
This creates a table that's visible in SQL as MY_SCHEMA.Person.

How to use hibernate.default_schema and hibernate.default_catalog

I am using Mysql and earlier in my hibernate configuration file I mentioned
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
as the connection url where TestDB is the schema I am connecting to.
I want to specify the default schema in configuration file as
<property name="hibernate.connection.url">jdbc:mysql://localhost</property>
<property name="hibernate.default_schema">TestDB</property>
but it is not working in this way and It gives me an error saying that
java.sql.SQLException: No database selected
Can anyone help me with an example of how to use hibernate.default_schema , hibernate.default_catalog in hibernate configuration file?
You should use hibernate.default_catalog instead of hibernate.default_schema.
According to the MySql documentation the connection url should have the following format:
protocol//[hosts][/database][?properties]
where
database
The default database or catalog to open. If the database is not specified, the connection is made with no default database. In this case, either call the setCatalog() method on the Connection instance, or specify table names using the database name (that is, SELECT dbname.tablename.colname FROM dbname.tablename...) in your SQL statements. Opening a connection without specifying the database to use is, in general, only useful when building tools that work with multiple databases, such as GUI database managers.
Imagine we have the following MySql databases:
create database DB_A;
create database DB_B;
create table DB_A.TST_EMPLOYEE(
emp_id int primary key,
emp_name varchar(100)
);
create table DB_B.TST_EMPLOYEE(
emp_id int primary key,
emp_name varchar(100)
);
then we can specify the database connection in the hibernate.cfg.xml in the following way:
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306</property>
<property name="hibernate.default_catalog">DB_A</property>
<property name="hibernate.connection.username">your_user</property>
<property name="hibernate.connection.password">your_pass</property>
declare entities for DB_A.TST_EMPLOYEE and DB_B.TST_EMPLOYEE tables in the following way:
#Entity
#Table(name = "TST_EMPLOYEE")
public class EmployeeA
{
// ...
}
#Entity
#Table(name = "TST_EMPLOYEE", catalog = "DB_B")
public class EmployeeB
{
// ...
}
and then use them in the usual way. Also for the native queries you can use the {h-catalog} placeholder for the default catalog specified in the hibernate.default_catalog property.
P.S. I have to say that the catalog and schema notions can have quite different meaning from database to database. See this for the reference.

Can Spring Batch use MySQL for its internal BATCH_ tables?

I have been using Oracle for this without any trouble but I then had to switch it all over to use MySQL and am seeing this error during initialization:
org.springframework.dao.DataAccessResourceFailureException: Could not obtain sequence value; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table 'BATCH_JOB_SEQ' in field list
The tables are present so its something else going wrong here. After debugging I captured the actual sql it was trying to perform to get the sequence:
select BATCH_JOB_SEQ.nextval from dual;
Which is obviously an Oracle statement!
My config states this to setup the connection:
<bean id="springDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.252.205.5:3306/MASKNG" />
<property name="username" value="MASKNG" />
<property name="password" value="maskng" />
</bean>
Any help appreciated...
jobRepositoryFactoryBean.setDatabaseType(“mysql”)
Seems like there is no BATCH_JOB_SEQ created here in MySQL.
You need to create the sequence for that. Refer How do I create a sequence in MySQL? for creating sequence.

Create a cover index with "Include" columns using nhibernate mapping file

I need to create a non-clustered index with INCLUDE columns (see the <create> tag below). Here's the mapping file:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyApp" assembly="MyApp">
<class name="User" table="user" >
<id name="Id" type="Guid" column="user_id">
<generator class="guid.comb"/>
</id>
<property name="Name" column="name" not-null="true" />
<property name="Phone" column="phone" />
<property name="Zipcode" column="zipcode" />
</class>
<database-object>
<create>
CREATE NONCLUSTERED INDEX [IX_user_zipcode_id]
ON User (Zipcode)
INCLUDE (Name, Phone)
</create>
<drop>
DROP INDEX IX_user_zipcode_id
</drop>
<dialect-scope name="NHibernate.Dialect.MsSql2000Dialect"/>
<dialect-scope name="NHibernate.Dialect.MsSql2005Dialect"/>
<dialect-scope name="NHibernate.Dialect.MsSql2008Dialect"/>
</database-object>
</hibernate-mapping>
The problem I'm having is the index is not created at all. Nothing appears to be happening. This is my first time using <database-object> so I may be doing something wrong here.
I'm guessing INCLUDE is Sql Server specific which is why the dialect-scope is there. I know how to create a single and multi-column index, but this is not what I want. I want a single column index on zipcode and all other columns in the User table part of the INCLUDE clause of the query. Is there any way to create this type of index using the mapping file or some other way?
This is probably a long shot, but it would be nice to not have to specify every column but the indexed one in the INCLUDE part of the query... Instead to just let nhibernate add any new columns to the index that are added as properties to the mapping file.
So part of the problem was indeed my lack of understanding the database-object tag due mostly to poor documentation. From what I've gathered, the <create> and <drop> tags are only used when using SchemaExport like so:
Dim schemaExport As SchemaExport = New SchemaExport(NhibernateConfiguration)
schemaExport.Execute(False, True, False)
My app doesn't create the schema using that class. Instead it uses SchemaUpdate so the schema isn't blown away every time (the database may already exist on the users machine):
Dim schemaUpdate As SchemaUpdate = New SchemaUpdate(NhibernateConfiguration)
schemaUpdate.Execute(False, True)
That was the problem. The next logical question to ask is then how do you execute sql using SchemaUpdate. The answer... you can't. See this post: https://forum.hibernate.org/viewtopic.php?f=6&t=969584&view=next
Alas I am left to use raw sql. Maybe some day they will add an <update> tag.

How can I set the Nhibernate type generator to increment when working with SQL Server 2008?

Using HBM files to map my types.
One of my classes uses bag of items called PartnerEnv. One of their fields is set to be the id which should be generated using increment. for some reason I am getting the following error:
could not fetch initial value for increment generator[SQL: SQL not available]
Inner details: "{"Invalid object name 'jj.dbo.Partners2Env'."}"
If I change the generation method to assigned everything is ok.
I will appreciate any help given!
Can you set your Id column on the PartnerEnv table (or whatever that table is called) to an Identity column and then use the following in the .hbm file for that class?
<id name="Id" type="Int32">
<column name="Id" />
<generator class="identity" />
</id>