Constrains on class name for hibernate query in java - java

Sorry if it is a stupid question but I don't know Java almost at all.
I have a table "Orders" in a postgreSQL database, which I access by Hibernate, mapping the table to a class:
#Entity
#Table(name = "Orders")
public class Orders { ... }
This works. However, if I change the class name to "Order", thus:
#Entity
#Table(name = "Orders")
public class Order { ... }
I get an error:
org.hibernate.hql.ast.QuerySyntaxException: Orders is not mapped [from Orders]
of course I have already updated the hibernate xml config file, switching from
<mapping class="<path>.orders.Orders"/>
to
<mapping class="<path>.orders.Order"/>
any idea why ? What am I missing ? The mapping between the DB table and the class is established only on the basis of the #table annotation and not on the class name, isn't it ?

You're missing the fact that JPQL is not SQL. It works on entity names and property/field names, not on table names and column names. Since you changes the name of the entity class from Orders to Order, you need to change your JPQL queries from
select o from Orders o ...
to
select o from Order o ...
The name of the table that the entity maps is completely irrelevant.

Related

Creating missing subclass entity when super exists

I have 2 tables S and I on the database (with a 1:1 relationship), they both have the same id as pk and the hibernate classes I've created are like these:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class S {
#Id
#Column(name = "id")
#GeneratedValue(...)
#SequenceGenerator...
private long id;
....
}
#Entity
#PrimaryKeyJoinColumn(name = "id")
public class I extends S {
....
}
Because of historical reasons, in the database there are objects of type S but not the associated objects of type I. I want to create those I type objects using hibernate. How can I do that? Can I create an I type object from an left join HQL query like this?
select i from I i right join i.id s where s.id = :id
If I try to create a new I entity (new I()) and then persist it, I only managed to get some exceptions as it tries to create an already existing S record. I can't do a simple read/load for I entity as I record does not exist yet. How can I do to create this missing I part entity?
PS I will adjust the question if you point me the unclear things
One approach that will certainly work for you (while is isn't clean one) is to create I records with SQL inserts directly: insert into I_table values (...).
When there are corresponding records in I_table, ORM will start load your objects with I type.
If you have to stay with your ORM and you can delete S records then you can
Load S by id
Delete S (flush? based on your flush mode)
Create I
Copy S values into I
Save I
What you're trying to create is an entity hierarchy. So have to map the entities correctly. The following is probably what you need:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn(discriminatorType = DiscriminatorType.CHAR)
#DiscriminatorValue("S")
public class S {
#Id
//........
private long id;
....
}
#Entity
#DiscriminatorValue("I")
public class I extends S {
....
}
With this setting the table S will contain a column named DTYPE (for discriminator type) which identifies whether a row belongs to S or I; this is the default; if you don't want that you have to give a name for the DiscriminatorColumn annotation.
Create an instance of S and save
Create an instance of 'I' by populating the inherited properties (i.e., the properties of S) and its own properties, and save.
When you create a query targeting I, you'll get only instances of I, but if your query targets the S, you'll get instances of both entities.

Update UniqueConstrains on a JPA table

I have a table defined as follow:
#Entity
#Table(
uniqueConstraints = {#UniqueConstraint(columnNames = {"reward_id", "transaction_id"})}
)
public class ShipmentItem extends Model {
...
}
I want to change the unique constraint to make it more relaxed:
#Entity
#Table(
uniqueConstraints = {#UniqueConstraint(columnNames = {"reward_id", "transaction_id", "sku"})}
)
public class ShipmentItem extends Model {
...
}
The updated code compiles, but JPA doesn't change the table schema. Is there a configuration setting I need to use?
If JPA cannot do this, what's the systematic approach to this problem? I can write migration, however, JPA generates the name for the constraint automatically, so it's not obvious how to drop the old constraint.
Not sure if it matters, but I am using hibernate and mysql.
Since you are using Hibernate, there is a property for automatically updating your schema: hibernate.hbm2ddl.auto with the value update
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html
(But be aware that it is not recommended to use it on Production)

Hibernate doesn't see tables with quotes in name

I have some tables in db(postgresql) with names like this "Test".When i try create java classes from this tables with hibernate its not happening. I get classes from tables with names like this test. How to make hibernate can see tables with quotes in names?
UPDATE
Maybe i write question not correct. But i cant create java classes and i want to know how to do reverse ingenering with tables which have names in qoutes. I cant delete qoutes from table names and column names couse they have names like Type and Full.
By default, Hibernate assumes the database table name is the same as the class name, but you can override this behaviour via the #Table annotation:
#Entity
#Table(name="\"Test\"") // Will use "Test" (including the quotes) as the table name
public class Test {
The #Table annotation is used to specify the table to persist the data. The name attribute refers to the table name. If #Table annotation is not specified then Hibernate will by default use the class name as the table name. So your database's table name is "Test" then you should use your class name is "Test".
Please check your database with
select * from """Test""" if your table name is "Test".
Your entity class should be
#Entity
#Table(name = "\"\"\"Test\"\"\"")
public class Test {
}
It seems that you are not using annotations as of now...
So in case you want to use "Test" as table name you should define the mapping of POJO with your table either via annotations as defined by Bohemian
#Entity
#Table(name="\"Test\"")
public class Test {
or define in the Test.hbm.xml in which you have to map your table and fields to java class and columns.
Alternately, you can specify the schema and database name inside #Table annotation.
#Entity
#Table(name = "Test", schema = "public", catalog = "TestDatabase")
Hibernate will recognize the table without the need to escape double quotes.

Inheritance on Hibernate objects without table mapping

I want to use hibernate objects in project as defined below.
#Table(name = "Parent")
class Parent{
int id;
String name;
}
#Table(name = "Child")
class Child extends Parent{
String schoolNo;
}
But in the database;
There is no relation with these two table.
Parent tables columns are; id, name
Child tables columns are; id, name and schoolNo
If I use
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
when I send a query for Parent object, hibernate use UNION on Child and Parent tables but I want to select from only Parent table.
And if I use
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
hibernate wants a discriminator column.
I need hibernate sends select query for each class to its table.
Best regards.
TABLE_PER_CLASS is the correct strategy here.
It's odd that Hibernate generates a union query over both tables, but that should still work. The subquery over the wrong table won't find anything, so the results will be correct. This sounds like a bug in Hibernate's query generation for subclasses.
In a similar situation, I use #Inheritance(strategy = InheritanceType.JOINED) on the parent table.
See more info in the Hibernate docs: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#d0e1168

What's the difference between the name argument in #Entity and #Table when using JPA?

I'm using JPA2 and both #Entity and #Table have a name attribute, e. g.:
#Entity(name="Foo")
#Table (name="Bar")
class Baz
What should I use, which ones are optional?
In my specific case I have a class User and a class Group, which have additional requirements (as far as I understand) because they are reserved words in SQL.
How would a working solution look like and with which name would I refer to the entity when writing queries?
Update: I added name="GROUPS" to both annotations in Group and did the same for User, but now I get this error:
Exception Description: The table [USERS] is not present in this descriptor.
Descriptor: RelationalDescriptor(example.Group --> [DatabaseTable(GROUPS)])
and this error
Internal Exception: java.sql.SQLException: Table not found in statement [SELECT ID, MAXIMUMROLE, MEMBERSHIPS_ID FROM USERS]
#Table is optional. #Entity is needed for annotating a POJO class as an entity, but the name attribute is not mandatory.
If you have a class
#Entity
class MyEntity {}
A table with name "MyEntity" will be created and the Entity name will be MyEntity. Your JPQL query would be:
select * from MyEntity
In JPQL you always use the Entity name and by default it is the class name.
if you have a class
#Entity(name="MyEntityName")
#Table(name="MyEntityTableName")
class MyEntity {}
then a table with name MyEntityTableName is created and the entity name is MyEntityName.
Your JPQL query would be :
select * from MyEntityName
The name in #Entity is for JPA-QL queries, it defaults to the class name without package (or unqualified class name, in Java lingo), if you change it you have to make sure you use this name when building queries.
The name in #Table is the table name where this entity is saved.
#Entity is useful with model classes to denote that this is the entity or table
#Table is used to provide any specific name to your table if you want to provide any different name
Note: if you don't use #Table then hibernate consider that #Entity is your table name by default
#Entity
#Table(name = "emp")
public class Employee implements java.io.Serializable { }

Categories

Resources