I have a problem that I've been struggling to solve but I'm not getting anywhere.
I'm using JPA Hibernate to create tables, but instead of creating the table, he shows me the error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table ‘escola.tab_alunos’ doesn’t exist
Here's my persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version=“2.0”>
<persistence-unit name="banco" transaction-type="RESOURCE_LOCAL">
<description>
Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.halyph.sessiondemo.Event</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/escola" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="0000" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
And here's the class Aluno:
#Entity
#Table(name=“TAB_ALUNOS”)
#SequenceGenerator(name=“TAB_ALUNOS_PK”, sequenceName=“SEQ_ALUNOS_PK”, allocationSize=1)
public class Aluno {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="TAB_ALUNOS_PK")
private Long id;
#Column(length=10, nullable=false)
private String matricula;
#Column(length=100, nullable=false)
private String nome;
#Column(length=9 ,nullable=false)
private String sexo;
#Column(name="DATA_NASCIMENTO", length=10, nullable=false)
private String dataNascimento;
#Column(length=30, columnDefinition="DEFAULT 'Ativo'")
private String situacao;
// ....
}
Any idea on how can I solve this problem?
Just for the record, the first time I started the project, it worked just fine, but due to a mistake I've made, I had to drop the table, after that hibernate stopped creating the table and now I can't do anything
Modify
<property name="hibernate.hbm2ddl.auto" value="update" />
to
<property name="hibernate.hbm2ddl.auto" value="create" />
The value="update" modifies the existing table while value="create" creates a table, but if the table already exists, it drops the table with the data and creates a table again.
Change <property name="hibernate.hbm2ddl.auto" value="create" />
Refer here for all possible values of hbm2ddl.auto
Hibernate hbm2ddl.auto possible values and what they do?
The error shows up because your persistance.xml has been configured to update tables. During the first run, there are no tables that have been created, and thus nothing to update.
On the first run, set <property name="hibernate.hbm2ddl.auto" value="create" /> so that a table can be created from your pojo. Then, set it back to <property name="hibernate.hbm2ddl.auto" value="update" /> so that your tables can be updated instead of being created at each run
Provide schema as well along with table name e.g.
#Table(name=“TAB_ALUNOS”, schema = "dbo")
I tried changing it to:
<property name="hibernate.hbm2ddl.auto" value="create" />
and i have also tried changing to:
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
Neither one of those two worked.
Related
I am using JPA with EclipseLink for PostGreSQL. Due to some product requirement I want to switch the schema runtime. I am planning to do it in "customize" method of SessionCustomizer as shown below
#Override
public void customize(Session session) throws Exception {
System.out.println("calling customize ###################");
if (this.schemaName != null || !this.schemaName.isEmpty()) {
session.getLogin().setTableQualifier(schemaName);
}
I set MySessionCustomizer in peristence.xml.
But don't know when and who will call MySessionCustomizer's customize method.
Please help me to understand this.
EDIT:
Here is my persistence.xml
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="test" >
<class>com.demo.Student</class>
<properties>
<property name="eclipselink.session.customizer" value="com.demo.MySessionCustomizer"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/MyDB" />
<property name="javax.persistence.jdbc.user" value="username" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
</persistence>
I am able to connect to the database using this persistence.xml and read/write from public schema of the database. However, I want to read and write from different schema and I also want to be able to change the schema at runtime.
I tried using "?currentSchema=MYSCHEMA" in DB URL, but it didn't work.
I'm currently using the JPA specs to query my objects from the database.
Everytime there's a change made by me (my instance of the software), the items would be properly refreshed.
But, if there's another change made by someone else (other instance, or database change), the items are'nt being properly refreshed.
I'm using a simple "find" with "refresh"
Object found = getManager().find(getModelClass(), id);
getManager().refresh(found);
I'm using a DAO Hierarchy, the "getModelClass" returns my #Entity class like
#Override
protected Class<?> getModelClass() {
return ProductCategory.class;
}
And my Manifest / persistence.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="casa" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<!-- localhost -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/database" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.jdbc.wrap_result_sets" value="false" />
<property name="hibernate.hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
Also each "DAO" have and instance of and EntityManager of it's own.
What I might be doing wrong ?
Appreciate the help!
Seems like my problem was simple.
The refresh transaction to be properly refreshed from the database needs to be commited
getManager().getTransaction().begin();
T found = (T) getManager().find(getModelClass(), id);
getManager().refresh(found);
getManager().getTransaction().commit();
I have an application that uses a set of JPA entities that are located in 2 different databases. I configured it with multiple persistence units.
The problem is that I want to auto-generate the schema using schema-generation, and all the entities are created in both databases.
I have in both PUs:
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
And, yes, I want to use the metadata to get the entities automatically. I do not want to provide a manual script, because I would need to keep it up to date with the entities.
Is there a way to mark which entity to be generated by which PU?
-edit: please be aware that adding "schema" property on #Table does not resolve the problem, because each PU will try to create the same entity in the right schema, and there will be errors because the tables will already exist.
Yes, you can do that. You need to list the entities under each persistant unit, and also DISABLE the auto discovery of the unlisted entities explicitly with <exclude-unlisted-classes>true</exclude-unlisted-classes>.
<!-- Unit 1 -->
<persistence-unit name="Unit1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.your.class.A</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.username" value=""/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
</properties>
</persistence-unit>
<!-- Unit 2 -->
<persistence-unit name="Unit2" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.your.class.B</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.username" value=""/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
</properties>
</persistence-unit>
Edit
If you are using annotations configuration, then
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setPackagesToScan("com.A");
And another factory for another entity manager with a different package name.
I found a way: I will use "schema" property in #Table annotation for each entity and then I would enable only one PU to auto generate the tables.
I am trying to store an image in the database but when I read the value I am getting always null.
I've tried several combinations of following annotations but result is always same:
#Lob
#Basic(fetch = FetchType.EAGER)
#Type(type="org.hibernate.type.BinaryType")
private byte[] image;
persistence.xml:
<persistence-unit name="primary" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/WheelGoDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
</properties>
</persistence-unit>
When I use only #Lob I've noticed that using pgAdmin i see numeric value. Otherwise I see binary data. My questions are:
Is there reliable way to store and read binary data using JPA2?
Is there way to read binary data in postgres? Because right now I am not sure if they are even correctly stored.
As I am trying to map Entity to tables using JPA (Hibernate implementation) I found something confusing
when i use annotation on getter, things are OK
#Column(name = "main_battery_voltage", precision = 2)
public float getMainBatteryVoltage() {
return mainBatteryVoltage;
}
but When I try the same thing on field, field name is used and attribute
#Column(name = "main_battery_voltage", precision = 2)
private float mainBatteryVoltage;
System ignores name attribute, runs with column name mainBatteryVoltage in DB and consequently failed task.
I am using MySQL and this is the persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="SolarPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.cs.solar.db.entity.User</class>
<class>com.cs.solar.db.entity.Lamp</class>
<class>com.cs.solar.db.entity.Project</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<!--<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>-->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/SOLAR"/>
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="admin" />
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.max_fetch_depth" value="3"/>
</properties>
</persistence-unit>
<persistence-unit name="TestSolar" />
</persistence>
Although it works now, I am curious what cause this problem, thank
You can find a short explanation here:
Hibernate Annotation Placement Question
The point is:
"the access type used by Hibernate will be field or property. The EJB3 spec requires that you declare annotations on the element type that will be accessed, i.e. the getter method if you use property access, the field if you use field access. Mixing EJB3 annotations in both fields and methods should be avoided. Hibernate will guess the access type..."