Is there a way to check if a certain MySQL column has a specific character set and collation with JDBC?
For those who need some background informations: The application I am working has changed its database layout with new versions. The update mechanisms was implemented rather basic: during startup, the application checks if the change is already there and, if not, alters the table accordingly. Right now I need to change an existing column to be unique and case sensitive (which means, I need to change the column's character-set and collation accordingly).
You will have to query it from INFORMATION_SCHEMA.COLUMNS. The CHARACTER_SET_NAME and COLLATION_NAME fields are what you need.
There is nothing in the JDBC spec that provides access to this.
Related
Does anyone know of a standard way to retrieve value defined with Defaults in a database when you insert?
These are not primary keys but other columns, the getGeneratedKeys method only returns for auto-increment, but I have other defaults like LastUpdate (date) or CreatedOn (date).
I realize that some databases like MSSQL have an output option or Oracle Return option, but I'm looking for a common way to do it.
Use the generated key so you can then follow up with a SELECT allTheFieldsYouCareAbout FROM tableYouJustAddedSomethingTo WHERE unid = generatedKeyYouJustGot.
Yeah, that's annoying and somewhat dubious from a performance perspective (the primary key is doubtlessly indexed, so not too pricey, but it's still another back-and-forth over TCP or whatever pipe you're using to talk to your database).
It's also the only way that reliably works on all major JDBC drivers.
CrudRepository#save doesn't allow you to use default columns. null-fields of an entity are interpreted as NULL not DEFAULT.
If I use a custom #Query("INSERT INTO ... DEFAULT ..."), then I'm unable to obtain the ID of the inserted row.
There is currently no build in way of using the default values from the database.
While #Jay's answer isn't aimed at Spring Data JDBC, the approach of setting the attributes to their default value in the constructor does work with Spring Data JDBC.
The alternative would be to implement a custom method which does the insert and retrieves the default values back from the database.
AFAIK not all databases support more then one return value from an insert so you might have to actually reselect the data written to the database.
Similar to here I'm annotating my class with
#Table(indexes = {#Index(columnList = "name")})
which attempts to create a non-unique index with the maximum length of the varchar column. Unfortunately that's not possible because it's a varchar(255) column of type utf8mb4. phpMyAdmin added KEY '...' (name(191)) by clicking on the respective buttons in the UI, so at least my software runs efficient queries now.
Now I was wondering if it's possible to have my Java class auto-generate the index with limited length upon creating the database schema? The code builds on spring-boot-starter-data-jpa:1.4.2.RELEASE.
There are other answers than trying to get the 3rd party software to do something it may or may not allow for.
Live with 191 limitation on the column size. Or, do you really have a max between 191 and 255.
Change to utf8 (from utf8mb4). And lose the ability to store Emoji and some Chinese characters.
There is a clumsy process in 5.6 to raise the 767 limit you are bumping into.
Upgrade to 5.7, which makes virtually eliminates the problem.
You should only use the JPA generated table scripts as a starting point, and you should never use JPA to create you tables in production.
If you have "create table" privileges, so you don't need a DBA to create and modify the database, then I recommend that you use Flyway to manage database creation and migration. If you need to be database agnostic, and like long XML files, you can also use LiquideBase.
With flyway, you would add a new script every time you add one or more entities. I typically let JPA create the script, and then copy what I need, and maybe do some modifications - for instance varchar(255) means 255 bytes on some databases, so you may want modify that if you are storing something other than Latin-1.
Flyway is very simple to use, and it is fully integrated into Spring boot, so you just add the unique index the way you want it in the first (or later) flyway script src/main/resources/db/migration/V1__initial_script.sql.
I read the discussion about using hbm2ddl.auto=update in order to auto-update changes to the database schema.
The thread is from 2008 and I do not know how secure it is to use the auto-update mode today.
We are running a small JavaEE on a Glassfish with Hibernate 4.3.11 and PostgreSQL. We plan to use continious integration with Jenkins.
Is it useful to work with hbm2ddl.auto=update enabled? Or is it better to use an easy alternative to update/check the updates maybe manually?
I know it is hard to give a blanket statement.
You should not use hbm2ddl.auto=update to update production databases.
Few reasons:
Hibernate will only INSERT missing columns and not modify existing columns. Therefore, if you rename a property (Client to Customer), Hibernate will create a new column Customer, leaving the column Client untouched. You will need to manually "move" the data there and remove the orphan column.
Hibernate will not remove constraints on no longer mapped columns. Thus, if your Client column was NOT NULL, any insert query to that table will now fail in the first place, because Hibernate won't provide any data for the orphan column (Which still has it's NOT NULL constraint) anymore.
Hibernate will not touch data types of existing columns. So, if you change a property type from String to Date - Hibernate will leave the column definition as varchar.
Hibernate does not remove columns of which you deleted the property, leading to data-polution and worst-case (The constraints remain in place) to no longer working applications.
If you create additiional constriants on existing columns - hibernate will not create them, because the column already existed before. (You might miss important contraints on the production db you added on existing columns)
So, perform your updates on your own is safer. If you have to take into account what hibernate is doing and what not - you'd better do it on your own from the scratch.
How can I set Postgres schema dynamically in Java? I tried doing:
this.getDataSource().getConnection().setSchema("mySchema");
I am using spring-jdbc and this is a JdbcDaoSupport instance.
Note: I don't want to go to database twice, so set search_path does not solve my problem efficiently.
Run the statement:
set schema 'myschema';
to change the current schema
Or simply set the search path, so that you can access the tables in e.g. the public and myschema:
set search_path to public, myschema;
(Note the difference in how you specify the schema name in the two statements: the first one has to use single quotes, the second one does not)
You can also change the search path permanently for a specific user, by using alter user....