Hibernate reverse engineering of a PostgreSQL database - sql

I am having some trouble generating my DAO/POJO code using Hibernate for a PostgreSQL database written using the CamelCase notation. Everything works fine until the code generation time: only my lowercase tables are generated!
If I have a table called Person, the Hibernate Configurations View will show it but without any attributes. Say I have another table, car, it will be shown with all of its attributes. On code generation time, furthermore, car will appear in the destination package, while the CamelCase tables won't, as it is completely ignored.
I found a way of overriding the default metadata generation class (JDBCMetaDataDialect), but it doesn't work. Even if it did work, I think my POJO/DAO objects would not work, because the PostgreSQLDialect dialect would handle the lowercase tables (and attributes?) in a wrong way.
How can I solve this issue? It looks like a bug, but I'm not sure of it.

I ended up always returning true from my generation method:
public boolean needQuote(String name) {
return true;
}

Related

Storing geometries as SDO_POINT_TYPE with Hibernate 5 and Oracle

I am using Hibernate 5.1.0.Final in a Java application for database persistence. That will be handy for us as we expect to hit Oracle and Postgres instances, so we can have this ORM as an abstraction layer.
In a former issue when querying geometries using Hibernate-spatial I posted some of my configuration.
The problem now is when we persist some geometry fields in Oracle. In my POJO I have an import :
import com.vividsolutions.jts.geom.Geometry;
So that I define the following attribute in my class :
#Column(name = "geom")
protected Geometry geom;
It gets persisted and I can use predicates to query it. But looking inside the database I can see the content of the geom field is :
MDSYS.SDO_GEOMETRY(2001,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,1,1),MDSYS.SDO_ORDINATE_ARRAY(0.094,51.488))
Instead of what I would like, which is faster to query and is recommended by Oracle :
MDSYS.SDO_GEOMETRY(2001,4326,MDSYS.SDO_POINT_TYPE(0.094,51.488,NULL),NULL,NULL)
What should I do in order to store this as a point (SDO_POINT_TYPE) and not as an array (SDO_ELEM_INFO_ARRAY) ?
EDIT : I tried changing to Point as shown below, but it didn't make a difference, as far as I can tell.
import com.vividsolutions.jts.geom.Point;
(...)
#Column(name = "geom")
protected Point geom;
It looks to me that currently there is no way to force Hibernate to store points as points instead of an array of coordinates. I went deeper into this and I came out with a tweak to the source code mostly for me, but also for those who need to do so.
I created a pull request to the original project. Even though it may or may not be considered for the master, anybody can potentially create their own customized version of OracleJDBCTypeFactory.java taking it from here :
https://github.com/GeoLatte/geolatte-geom/pull/42
Update : This was merged into master. It should be ready for next release of geolate-geom. As per #maesenka 's comment :
You must set a system property GEOLATTE_USE_SDO_POINT_TYPE=true to enable this feature.

Refering to a particular parent, in case of multiple, and then retrieving its attribute

If an sobject has more then one parent, how do we lexically refer any one its parent in order to get its attributes?
I need it to write a naming convention for that particular sobject.
The sobject and its parent sobjects are connected in the schema by code.
What I tried was something like:
{project.code}/{sobject.parent01_code}/{sobject.code}/{context}
which works but {sobject.parent01_code} is not what I want, because it is not quite self-explanatory and cryptic to be used for naming of files and directories.
I rather want to something like ../{sobject.parent01.name}/.. or ../{sobject.parent01_code.name}/.. which returns Reported Error: "too many values to unpack" error.
So how can I achieve such a thing? Given, if I am not wrong, the absence of a full brunt expression language in the setting of naming conventions, which, if a present, would enable something like #SOBJECT(parent01["code", {sobject.parent01_code}]).name.
These are two separate questions but put into one because it relates to one particular problem.
This used to be unsolved in earlier versions of tactic. In 4.1 however, you can also use the expression language in the braces.
ex: {project.code}/{#GET(example/some_stype.name)}/versions
If some_stype is the parent of to the current stype's, you'll get the corresponding sobject's name.

How to design my test automation

Here is my test scenario.
When a command line executes - lot of values are written to different tables in a db.
There are multiple command line options and many values/tables to be verified in the db. How should I go about designing the check for values in db?
What I done have so far -
execute the command
Connect to db
run the query particular to the command (this will be very specific to the command on what tables I need to look in)
from the dataset returned check if dt[row][col]="value i expect".
Advantage here is that I have to write less code as part of framework.
Downside of this is that I have to write more code when developing each tests, not streamlined and I may get column names wrong sometimes.
So I am trying to see if I streamline the check better. Something like declare a class (for a table)with columns as exposed properties. This way i wont get the column names wrong at least.
Is this the simplest approach ( for the long run? I want to write more reusable code). If not, what best way there is?
Is there a easy way to export tables/column values from db to a c# project file (as a class/code) so that I don't have to put everything in code again.
Let me know if any details are not clear or if I would like me to elaborate bit more on the details.
Thanks for looking.
I don't know of a standard approach for this problem, but I'll offer some ideas.
I usually find myself creating classes to represent tables to take advantage of compile-time checks, so I think that's a good way to go. You might want to look into Linq-to-SQL -- I think it can do a lot of this for you. I sometimes use ActiveRecord in Ruby for this purpose, even on C# projects, because development with it is very quick.
Alternatively, you might want to put the tests in text files:
Command:
command to execute
Expected Data:
SELECT column FROM table;
row name, column name, expected data
row name, column name, expected data
row name, column name, expected data
Expected Data:
SELECT column FROM table;
row name, column name, expected data
row name, column name, expected data
Then write a little code to load and parse your files, run the command, and compare the results. This would factor out only the things that change with each test, so I don't know if it can get much better.
Another idea is to try pulling common code into a base class and keep the varying code in subclasses. This design follows the Template Method pattern.
Example
class MyTest : CommandLineTest {
public String Command() { return "Command to execute"; }
public String DataRetrievalCommand() { return "SELECT column FROM table"; }
public DataResult[] ExpectedData() {
return [ new DataResult("column", "row", "value"), ...];
}
}
The superclass will use these methods to get the commands and values, but it will be the one doing all the actual work. Similar idea as the text files, but the test specification is kept in code.
Hope this helps or at least gets a few ideas flowing.

Fluent NHibernate - HasMany mapping with condition

I have a HasMany mapping that needs a condition. I have this partially working, but there's got to be a better way than what I'm doing. The condition I'm using needs to look at a property on another table that I'm joining to. What I have so far is:
HasMany<MetaData>(x => x.MetaData).Table("MetaData")
.KeyColumn("DefinitionID")
.KeyColumn("TableID")
.Where("metadatade1_.SourceTable = 'Providers'")
.Cascade.SaveUpdate();
In the code above, the where clause is referencing "metadatade1_", because it's trying to fully qualify the name, and that is the name NH is generating. I've tried using "MetaDataDefinitions.SourceTable" (MetaDataDef... is the physical table name), and also just "SourceTable" by itself, however none of these worked.
Is there a way to not have it try and fully qualify the name on the condition and just pass "SourceTable='Providers'" OR is there a way I can have it reference the generated name without me having to manually plug it in?
In short, no. The Where method (and respectively the where= attribute in HBM.XML) accept only raw sql, and as such is prone to the problems you're seeing.
Your best option is to not use a collection and instead rely on a query to retrieve your metadata instances.

NHibernate: Return A Constant In HQL

I need to return a constant from an HQL query in NHIbernate
SELECT new NDI.SomeQueryItem(user, account, " + someNumber + ")
FROM NDI.SomeObject object
I am trying for something like above. I've tried this:
SELECT new NDI.SomeQueryItem(user, account, :someNumber)
FROM NDI.SomeObject object
And then later:
.SetParameter("someNumber", 1).List<SomeQueryItem>();
But in the first case I get a 'Undefined alias or unknown mapping 1'. Which makes some sense since it probably thinks the 1 is an alias.
For the second I get a 'Undefined alias or unknown mapping :someNumber' which again makes some sense if it never set the parameter.
I have to believe there's some way to do this.
Please feel free to continue to believe there is some way to do this - but with HQL there isn't!
Why would you want to anyway? If you want to update the value this property to the value you specify, then do so after you've loaded the objects. Alternatively, if your result set doesn't quite match to your objects, you could alway use a SQL query (which you can still do via an NHibernate session). But the purpose of NHibernate is to map what's in your database onto objects, so specifying a manual override like this is quite rightly not allowed.
It sounds like there is a (small?) disconnect between your domain objects and your database model. What about creating a small "DTO" object to bridge this gap?
Have your query return a list of SomeQueryItemDTO (or whatever you want to call it) which, due to the naming, you know is not a true part of your domain. Then have some function to process the list and build a list of true SomeQueryItem objects by incorporating the data that is extraneous to the database.
If you're already using the Repository Pattern, this should be easier since all the ugly details are hidden inside of your repository.