NHibernate mapping: is it possible to insert values into the database via a mapping file without using a property? - nhibernate

I am writing an application which works with a legacy database (brownfield). I have a couple of tables in which I insert data. These tables have some fields which need values of which I do not want the properties in my domain entities. Is there a way to insert the default value into the field without having to create a property for it my mapping file? I cannot alter the database to create a trigger, so it has to be done via the mapping file/.net application.
Hope someone can help. I hoped I could use a formula, but that doesn't work and I couldn't find any other ways to do it either.

you could use a private / protected property.
That would mean introducing these fields into your domain model / mappings, but they would be limited to those, and not exposed to whoever uses your entities.
seems like a reasonable compromise to me.

You could use EventListeners
in the OnPostInsert / OnPostUpdate event you can get the db connection and ad-hoc execute a sql query.

NH makes it rather easy
using xml see here
using FluentNHibernate see here
the basic idea is to use PropertyAccessor on a non existing property which always has the constant value.

Related

rename database field in upgrade wizard of an extension in TYPO3 11

I have an upgrade wizard (TYPO3 11) which changes the data of a table.
This is done with the querybuilder:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tt_content');
$queryBuilder
->update('tt_content')
->set('CType', 'newCType')
->where($queryBuilder
->expr()
->eq('CType',$queryBuilder->createNamedParameter('oldCType')))
->execute();
But I also need to rename a field in a table:
ALTER TABLE tt_content RENAME COLUMN tx_myext_old_field TO tx_myext_new_field;
I can't find any documentation or example of doing this with the querybuilder.
The normal way woult be to provide a ext_tables.sql in your extension. This is read by TYPO3 to build a virtual "database scheme" how it should look.
The database schema analyser will than provide the information, and database alteration are suggested.
You could add a database must be up to date constraint to your upgrade wizard, that way it is ensured that the field is changed.
DTL is a special task, and you have to provide the correspinng queries yourself ... which are different for different dbms systems. So using the normal way would be recommended.
The platform/driver may have some generig helper methods providing some native sql parts for doing stuffs like that. The may be possible to provide custom stuff based on SchemaMigrator or SchemaManger etc - but thats low-level stuff.
doctrine/dbal directly do not really provide these DTL as API. And the querybuilder is not meant to be used for that low level stuff at all. That's the wrong tool for such tasks.
You can also change columns of core tables that way, by providing simply the table name and the column defintion only for the field you want to change.
The official way is to handle this with ext_tables.sql and the database schema analyser.
See: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtTablesSql.html
The concept of renaming a column could not work:
On installing the extension all new fields are generated (or should be generated if in composer mode). And as the extension should work with the new columns they are already defined.
And before the upgrade wizard could rename a column these columns are existent already which prevents a rename.
In the end I do a content copy enhancing the update query like this:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tt_content');
$queryBuilder
->update('tt_content')
->set('CType', 'newCType')
->set('tx_myext_newfield1',$queryBuilder->quoteIdentifier('tx_myext_oldfield1'),false)
->set('tx_myext_newfield2',$queryBuilder->quoteIdentifier('tx_myext_oldfield2'),false)
->where($queryBuilder
->expr()
->eq('CType',$queryBuilder->createNamedParameter('oldCType')))
->executeStatement();

How to change the database name dynamically in MyBatis XML file?

I am using Spring Boot with MyBatis. I have the following query in one mapper XML file.
<select id="someFunction" resultMap="someResultMap">
SELECT *
FROM p LEFT JOIN anotherDatabase.table AS q ON p.id = q.id
</select>
Actually "anotherDatabase" is hard-coded in my query because I do NOT want to add another data source for only this query. But how can I make this "anotherDatabase" name dynamically (maybe configure it in some properties file) as it may change in different environment deployed?
Though ugly solution, you can use a parameter: not a traditional JDBC/SQL parameter #{schema} but a direct parameter ${schema}. See the dollar sign ($) there?
When using a direct parameter ${param} you can insert whatever you want into the SQL. Even a entire whole SQL statement if you wish. Use it with care and only as a last resort.
Please carefully consider this insertion of direct parameters into the SQL is susceptible of SQL injection. You need to carefully control the value of the schema property/parameter, so it does not come from the user or any external source. If you do it like this, it will be safe to use.
However, a cleaner solution is to use a separate datasource. The only drawback is you may need to enable two-phase commit if you need transactions that emcompass tables from both datasources.

Nhibernate 3.1 SQL-(UPDATE, INSERT) stored procedure parameter order

I am trying to get an insert stored procedure to work on an entity mapped to a view. The problem is the syntax is something like
<sql-insert>EXEC InsertNote ?,?,?</sql-insert>
<sql-update>EXEC UpdateNote ?,?,?,?</sql-update>
<sql-delete>EXEC DeleteNote ?</sql-delete>
I have about 1500 of these, some with over 100 fields, to generate.
is there any way to KNOW what order nhibernate will generate the parameters in (other than verifying the orm call to the sql server through profiling)?
I realize model complexity complicates this currently, but I haven't found a current answer to this issue.
Thanks :)
The parameters are generated in the same order as the properties appear in the mapping file.
That said... this model is an huge waste of effort. Why use NHibernate if you have stored procedures for all operations? Why use stored procedures if you have NHibernate?

Execute sql CREATE TABLE query in Hibernate

I need to dynamically create a table using a Java method and tranform all its rows into a list of Mapping class objects. The questions are..
Is there a way to execute CREATE TABLE query dynamically?
I saw some examples using doInHibernate() but it didn't work when I tried it. Can I do this without the particular method?
You could just execute a native sql query: session.createSQLQuery("create table .....").executeUpdate(); where "session" is your Hibernate session.
If you already have the mapping files, though, you can just set the hibernate.hbm2ddl.auto property in your hibernate configuration to generate the schema based on the mapping files.
Try this:
session.createSQLQuery(query).executeUpdate();
another possibility would be:
createStatement().execute(someddl);

Can't load from Oracle when Id is Guid in NHibernate

We're saving an object to NHibernate where the Id is typed Guid. Based on other things we've found we have this as a type char(36).
We create an object and save it via NHibernate. This works fine and we see 64599239BB0C1C48B44C36D9F9267830 in the column.
When we then try to load using a guid we don't get any results and NHibernate Profiler shows that the WHERE clause is looking for 0x64599239BB0C1C48B44C36D9F9267830 which isn't matching.
Obviously we're doing something wrong.. so any ideas what?
The data type on the database should be RAW, and of 16 length. This is what trying to recreate the database using NHibernate produces.