I am using struts, now I have a question:
Is it possible the name of BO class be different from table name in database?
when I change the name, it makes error
Check a table name associated with your object if you use annotations.
#Entity
#Table(name = "yourtablename")
public class YourClass {...}
Related
I was trying to find an answer but, unfortunately, with no luck.
The data structure looks like this:
TABLE_X - contains userId, also userType telling if this is external or internal user
INTERNAL_USERS - contains key userId
EXTERNAL_USERS - also contains key userId
TABLE_X.userId is either INTERNAL_USERS.userId or EXTERNAL_USERS.userId.
Now, I would like to map an entity out of TABLE_X and have user object mapped to correct entity, either INTERNAL_USERS or EXTERNAL_USERS.
How should I do this?
Should I create two fields and map one to INTERNAL_USERS and one two EXTERNAL_USERS and just see which one is not empty?
If I understand correctly your question, what you have to do is to replicate structure of the TABLE_X columns with fields on the TABLE_X class, and add to fields one for INTERNAL_USERS.userID and one for EXTERNAL_USERS.userID
But if you store on TABLE_X.userType if a user is internal or external, I think that the best thing you can do is not create any other table, because you just have the information you need on your first table (TABLE_X). If you want to know all the users that are internal for instance, just do a SQL and select all the values from TABLE_X where userType = "Internal"
Use Hibernate inheritance. Check out the Table per class inheritance pattern. Here you have both INTERNAL_USERS or EXTERNAL_USERS data in TABLE_X with userType as the discriminator column.
http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e1191
Given the table structure, you can use JPA Inheritance as detailed here:
https://en.wikibooks.org/wiki/Java_Persistence/Inheritance#Example_joined_inheritance_annotations
In Hibernate you can model such relationships as follows. When querying for a User you can then rely on Hibernate to return an instance of the correct type.
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
public class User{
#Id
private Long userId;
}
#Entity
public class InternalUser extends User{
}
#Entity
public class ExternalUser extends User{
}
As noted in the article linked to, Hibernate does not require a discriminator column to be specified when using joined inheritance. It does however support a discriminator column if one is available. As you have one available in your schema - userType - then you could explicitly specify it if you wish. I imagine this would yield some performance benefit in terms of the generated SQL:
Mappings with optional discriminator column:
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="userType")
public class User{
#Id
private Long userId;
}
#Entity
#DiscriminatorValue("INT")
public class InternalUser extends User{
}
#Entity
#DiscriminatorValue("EXT")
public class ExternalUser extends User{
}
I have a next problem: I ve got a several tables in database, and somehow i need to make a query from one of them, but only in runtime i will know the name of needed table, so is any possibility to pass table name to #Table annotation of entity in runtime? All of these tables have absolutely identical schema. The only distinction - is name (BILLING_DATA_2016_1, BILLING_DATA_2015_12 etc.). Do somebody have an idea how can i pass the name of table dynamically? Or may be some hack with Queries and Inheritance?
You can try HibernateInterceptor. Place the {BILLING_DATA_PLACEHOLDER} string into your #Table annotation and just replace it on fly
public class HibernateInterceptor extends EmptyInterceptor {
#Override
public String onPrepareStatement(String sql) {
String prepedStatement = super.onPrepareStatement(sql);
prepedStatement = prepedStatement.replaceAll("{BILLING_DATA_PLACEHOLDER}", theRealSchemaName);
return prepedStatement;
}
}
Have not tried though
I have severals Entitys in my models but some of them share a same property namely Student i have created a abstract class like this.
#javax.persistence.MappedSuperclass
public abstract class StudentImpl
{
private Student student;
#ManyToOne(fetch=FetchType.LAZY)#JoinColumn(name="c01")
public Student getStudent(){return student;}
#Override
public void setStudent(final Student student){this.student=student;return;}
}
this is working like a sharm take a look that the 95% of them have mapped to C01 column in my MySQL table.
I have use this abstract class extending each of my Models with share the same property.
public class Teammate extends StudentImpl
The problem arise in some classes the Student property is mapped to a different column name in their table
Example
create table myTable
(
c02 int(11) NOT NULL, //student entity is mapped to c02 column instead of c01
)
As you can see they mismatch c01 and c02 and their column c01 column is mapped to a simple String instead of a Student.
I have try
#javax.persistence.AttributeOverride(name="student",column=#Column(name="c02"))
Wishing Hibernate could understand student property is mapped to column c02 in this Entity.
#javax.persistence.AttributeOverride(name="student",column=#Column(name="c02"))
public class AnotherClass extends StudentImpl
{
private String c01;
private String getC01(){return this.c01;} //Column c01 is mapped to a String
}
But seems not working because it Throws
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Column 'C01' specified twice.
This problem arise when i try to insert a new AnotherClass registry.
Why i am doing wrong is not possible accomplish it i am asking to much.
Thanks a lot and best regards from Venezuela.
Update
Solved i have find the solution thanks by #ddalton i used this and this is working
#javax.persistence.AssociationOverride(name="student",joinColumns=#JoinColumn(name="c02"))
You can use the AssociationOverride annotation to accomplish this:
http://www.objectdb.com/api/java/jpa/AssociationOverrides
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.
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 { }