JPA Unique Renaming Unique Index - java

I'm creating an entity called Person, basically there is a column Integer sin, with the annotation #Column(name="per_sin", nullable=true, unique=true") The problem in the persistence xml file I ended up setting the hibernate to create, so it will create all the tables in the database. The problem is that it adds a constraint as UK_jkdfjalkfa, but I wanted to rename the constraint to UK_per_sin, but I tried putting it as an annotation as #UniqueConstraint(name="UK_per_sin"), but when it persists it still keeps on adding the constraint with random generated value.

For me, it's possible renaming the Unique Key constraint including an option into the #Table JPA tag:
#Table(name="tableName",
uniqueConstraints = #UniqueConstraint(name = "UK_per_sin", columnNames= { "per_sin" } ))
And also not including the unique option into the #Column tag:
#Column(name="per_sin", nullable=true)

Related

Hibernate + JPA does not find the column for an #ElementCollection table

I am trying to add an #ElementCollection but the column is not found after the setup, so I constantly receive an error. I use Spring + flyway for the set up. Everything happens in the public schema
So here is my big object:
#Entity
#Table(name = "my_big_table")
MyBigObject{
#Id
#Column(name=COL_ID)
#GeneratedValue(generator="gen_name")
#GenericGenerator(
name = "gen_name",
strategy = "seq_name"
)
#AttributeAccessor(CommonConstants.HIBERNATE_ACCESS_PROPERTY)
private long id;
...
...
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(
name = "my_small_table",
joinColumns = #JoinColumn(name = "big_object_id")
)
private List<MySmallObject> mySmallObjects;
}
Here is my embedded object:
#Embeddable
public class MySmallObject {
#Column(name = "small_object_type")
private String smallObjectType;
}
Then besides the existing my_big_table table I add my_small_table using flyway
create table if not exists my_small_table
(
big_object_id bigint not null,
small_object_type varchar(64) not null
);
alter table my_small_table
add constraint FK_my_small_table
foreign key (big_object_id)
references my_big_table (id);
After this the my_small_table is successfully created but any instance of MyBigObject cannot be found because it looks for a column in the my_small_table that does not exist. As you can see it does not understand that the column name should use an underscore.
Big error trace ands with the following message:
Caused by: org.postgresql.util.PSQLException: ERROR: column mysmalltab0_.smallobjecttype does
not exist
09:17:24.994 INFO - STDOUT: Hint: Perhaps you meant to reference the column "mysmalltab0_.smallobjecttype".
Do you know what I could forget? Could lombock annotations that I also use for both classes spoil the picture?
As it's stated in the documentation:
By default, the placement of the #Id annotation gives the default access strategy. When placed on a field, Hibernate will assume field-based access. When placed on the identifier getter, Hibernate will use property-based access.
But the usage of the #AttributeAccessor leads to the changing access strategy for the field that hold #Id and as result your #Column(name = "small_object_type") annotation just was ignored. You can try to put it on the appropriate getter and it should work. But it's considered a good practiсe not to mix up access strategies for the entity fields.

org.hibernate.AnnotationException: Unable to create unique key constraint

I am using hibernate 4.3.5.Final version.
To handle reserve words at Database,I used a property in hibernate
hibernate.globally_quoted_identifiers = true.
And My pojo class having a unique column and it looks like
#Entity
#Table(name="theme1"
,catalog="theme2"
, uniqueConstraints = #UniqueConstraint(columnNames={"name1"})
public class Theme1 implements java.io.Serializable {
#Id #GeneratedValue(strategy=IDENTITY)
private Integer id;
#Column(name="name1", unique=true, nullable=false, length=32)
private String name1;
.....
Then when my SessionFactoryBean is loading it is failing with below error
Caused by: org.hibernate.AnnotationException: Unable to create unique key constraint (name1) on table theme1: database column 'name1' not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)
at org.hibernate.cfg.Configuration.buildUniqueKeyFromColumnNames(Configuration.java:1682)
at org.hibernate.cfg.Configuration.buildUniqueKeyFromColumnNames(Configuration.java:1614)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1450)
In the debugging process,I find issue is because of the property I add (hibernate.globally_quoted_identifiers).
When this property is added,Hibernate will append single quotes to handle reserved words.But while mapping from PhysicalToLogical,it is failed to map 'name1' with name1.Hence I got above error.
Can any one suggest how to handle above two cases(reserve words + UniqueConstraint) at a time.
When hibernate.globally_quoted_identifiers is set, Hibernate expects exact column name.
Check JPA with Hibernate 3.6.8.Final, PostgresSQL 9.1, SQLGrammarException - configuration issue? Weird SQL statement for more information.
So according to this, your column name and Table names in the pojo class need to be quoted.

JPA validation - OneToOne to same table

I just enabled the JPA validation in eclipse and in shows me some errors (The code is actually running fine).
I have an article entity and it holds a refrence to the next article and the previous entity (of the same type). The validator complains with the message:
Column "nextArticle" cannot be resolved on table "article"
What does this mean exactly? The SQL table has the columns as well. I tried also to map the variables to each other with the "mappedBy" and "JoinColumn" annotation, but was not able to resolve the validation error.
That's the class and validation error:
And that' the mapping:
Edit: Tried the suggestion from anttix: The columns in the table are named "nextArticle_id" and "prevArticle_id", so I came up with that code:
#OneToOne(mappedBy = "prevArticle")
#JoinColumn(name = "nextArticle_id")
public Article getNextArticle() {
return nextArticle;
}
#OneToOne(mappedBy = "nextArticle")
#JoinColumn(name = "prevArticle_id")
public Article getPrevArticle() {
return prevArticle;
}
But the validator complains now about the "mappedBy" annotation with the message:
In attribute 'prevArticle', the "mapped by" attribute 'nextArticle' has an invalid mapping type for this relationship.
Edit 2: I found the solution. I had to tell the validator the names of the columns in the actual database with the #Column annotation like this:
Eclipse can't find a column called prevArticle in the table. You should specifiy the column name for nextArticle and create a bidirectional relation with prevArticle to indicate that it does not need a foreign key column of its own.
#OneToOne
#JoinColumn(name = "next_id")
private Article nextArticle;
#OneToOne(mappedBy = "nextArticle")
private Article prevArticle;
You can omit the #JoinColumn from nextArticle if you want, but I would keep it there to make it clear which relation "owns" the foreign key column.
See also:
http://en.wikibooks.org/wiki/Java_Persistence/OneToOne

checking uniq constraints without using primary key

I am using hibernate only with Annotations. My table looks something like this:
#Entity
#Table(name = "NetworkType",
uniqueConstraints = {#UniqueConstraint(columnNames = {"network_id", "type"})})
public class NetworkType implements Serializable {
#Id
private long id;
#Column(name = "network_id", nullable = false)
private long networkId;
#Column(name = "type", nullable = false)
private String type;
...
Currently when I write the same NetworkType twice, it throws an exception due to the UniqueConstraint (which is expected).
My thoughts are to just read the item first before checking. The problem is, my primary key is the Id, which I need because other tables references this table.
What's the best way to query for item for the "network_id" and "type" to verify the combination doesn't already exist?
I know I can do this with a Query manually, but is there a more Hibernate-y way of doing it?
In general, what's the proper way to "get" an object without using the PK? Are Criteria or Query the best way?
#UniqueConstraint is mainly used by database schema generation tools to create the data base schema. If used, they will generate the table with the columns mentioned in the #UniqueConstraint having unique constraint defined.
#UniqueConstraint doesn't have any impact/usage during data manipulation.
If you wish to achieve unique constraint behavior on network_id and type columns and your schema is already created, update your database schema to add the unique constraint on network_id and type columns. as below:
ALTER TABLE NetworkType
ADD CONSTRAINT uc_network_id_type UNIQUE (network_id, type)
Hope this helps!

How can I ask Hibernate to create an index on a foreign key (JoinColumn)?

Here is my model:
class User {
#CollectionOfElements
#JoinTable(name = "user_type", joinColumns = #JoinColumn(name = "user_id"))
#Column(name = "type", nullable = false)
private List<String> types = new ArrayList<String>();
}
As you can imagine there would be a table called "user_type", which has two columns, one is "user_id" and the other is "type".
When I use hbm2ddl to generate the ddls, I want to have this table, along with the foreign key constraint on "user_id".
However, there is no index for this column. How can I get hibernate to generate the index for me?
Try an #Index annotation.
#Index(name="user_type_index")
There is also an #IndexColumn annotation used with join tables, but it doesn't seem to actually create an index, but controls which field defines order in list semantics.
The #Index column in this context does seem to create an index on the join table.
I'm dealing with a similar issue and I've found that some dialects will automatically index foreign keys and others wont.
Hibernate Dialect class and all subclasses which do not override the getAddForeignKeyConstraintString method (Oracle, SQL Server, etc) will not create an index on the foreign key.
MySQLDialect overrides that method and adds an index to every foreign key

Categories