I'm trying to use JPA in Wildfly (which uses Hibernate) with PostgreSQL. I turned on hibernate.show_sql so I can execute the same query in PgAdmin III.
The query is this one (EDIT: issuemanager_sch is the schema. Without it even in PgAdmin the query fails with "relation does not exist" error):
select issuetypet0_.id_issue_type as id_issue1_3_, issuetypet0_.name as name2_3_ from issuemanager_sch.issue_type issuetypet0_
When executed by Hibernate this is showed in both PostgreSQL log and Wildfly log :
relation "issuemanager_sch.issue_type" does not exist character 87
However, when I copy (to grant I'm executing the exact same query), paste and run the query in PgAdmin III it's executed normally and I get the results.
What could possibly be wrong with my configurations? (I tried with both quoted and unquoted queries and the results are the same: fails for Hibernate, works in PgAdmin III)
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="PersistenceManager" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:/datasources/issuemanager_pg</non-jta-data-source>
<class>com.im.issuerepository.domain.IssueTO</class>
<class>com.im.issuerepository.domain.IssueTypeTO</class>
<class>com.im.userrepository.domain.UserTO</class>
<class>com.im.userrepository.domain.GroupTO</class>
<class>com.im.userrepository.domain.RoleTO</class>
<validation-mode>NONE</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.default_schema" value="issuemanager_sch"/>
</properties>
</persistence-unit>
</persistence>
EDIT: issue_type table:
CREATE TABLE issuemanager_sch.issue_type
(
id_issue_type bigint NOT NULL DEFAULT nextval('issuemanager_sch.issue_type_seq'::regclass),
name text NOT NULL,
CONSTRAINT "PK_ISSUE_TYPE" PRIMARY KEY (id_issue_type)
)
EDIT: IssueTypeTO mapping:
#Entity
#Table(name = "issue_type")
public class IssueTypeTO implements Serializable{
#Id
#Column(name = "id_issue_type")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "issue_type_seq")
#SequenceGenerator(name = "issue_type_seq", sequenceName = "issue_type_seq", allocationSize = 1)
private Long idIssueType;
#Column(name = "name", length = 45)
private String name;
// getters and setters
}
Related
I need to just fetch some geospatial data (simple coordinates - POINTS) from MySQL db and use them in Java (NetBeans project). This is what I did so far:
Created MySQL db with following table:
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lokacija` point DEFAULT NULL,
`info` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
I also created NetBeans project and set up JPA and everything, added hibernate-spatial library to it and here is my persistence.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="testGisPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>model.Test</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.mysql.MySQLSpatialDialect"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:8889/dipl?zeroDateTimeBehavior=convertToNull"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value="root"/>
</properties>
</persistence-unit>
</persistence>
After that, created entity and besides all other properties, it also contains following:
...
#Column(name = "lokacija")
#Type(type="org.hibernate.spatial.GeometryType")
private Point lokacija;
#Column(name = "info")
private String info;
...
I also generated REST facade directly from NetBeans and I tried to print all items I fetch from the db (currently I have only two items with descriptions "first" and "second" and locations (1,1)) and here is what I get:
LOCATION: null
INFO: first
LOCATION: null
INFO: second
Any suggestions what else I should do in order to make this work?
I try to test the persistence of some entities with an in-memory H2 DB but I recognized that #SequenceGenerator will never be invoked as it should be, neither when running by build platform, nor when running it with RunAs->JUnit test in Eclipse.
What I can say for sure is that the sequences are generated inside the H2 DB. I can even select them when I connect to this generated H2. So it's definitely not a problem inside H2 but with Hibernate.
(Usually Hibernate automatically assigns an ID when persisting an Entity which needs one).
The entity
#Entity
#Table(name = "HOUSE_USERDATA")
public class UserData {
#Id
#Column(name = "HU_ID")
#GeneratedValue(generator = "SEQ_HOUSE_USERDATA", strategy = GenerationType.SEQUENCE)
#SequenceGenerator(sequenceName = "SEQ_HOUSE_USERDATA", name = "SEQ_HOUSE_USERDATA", allocationSize = 2)
private Long huId;
#Column(name = "HU_DATA")
#Size(max = 1000)
private String m_data;
#ManyToOne
#JoinColumn(name = "HR_ID")
private Registry m_registry;
//more code [...]
}
The reference in the referencing Entity...
#OneToMany(mappedBy = "registry")
private List<UserData> userDataList;
The persistence unit...
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.foo.bar.all.entity</class>
<!-- all entity references -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url"
value="jdbc:h2:inmemory;INIT=runscript from 'classpath:testscripts/drop_h2.sql'\;runscript from 'classpath:testscripts/create.sql'"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
The invocation in JUnit test...
Registry registry = new Registry();
registry.setClientId("clientId");
List<UserData> userDataList = new ArrayList<>();
UserData userData1 = new UserData();
userData1.setData("User defined data 1.");
userData1.setRegistry(registry);
UserData userData2 = new UserData();
userData2.setData("User defined data 2.");
userData2.setRegistry(registry);
userDataList.add(userData1);
userDataList.add(userData2);
registry.setUserDataList(userDataList);
entityManager.persist(registry);
Registry result = entityManager.find(Registry.class, "clientId");
//MUST NOT BE NULL, BUT IS NULL
assertThat(result.getUserDataList().get(0).getId(), is(not(nullValue())))
Other values are persisted properly. Only the IDs were not generated. (I wonder why this test works at all for all the other values since the ID is defined as NOT NULL in the generated DB, so there should be a persistence exception or something else).
Any ides why the sequence generator does not generate anything (I tried GenerationType.AUTO as well, but no difference)?
When you are doing entityManager.persist(registry) that is what it is going to do, store the Registry and check all the mappings for that class. It will encounter the collection of UserData objects, but because there is no cascade property matching the PERSIST it will not store the UserData objects.
It will only store the top level Registry object. If you want to change this add cascade={CascadeType.ALL} or at least cascade={CascadeType.PERSIST} to the #OneToMany annotation, to tell Hibernate it also needs to check the collection for new elements and persist those.
Or first store the UserData elements, before storing the Registry.
I'm trying to use pure JPA 2.1 as a standardized way to generate db schema.
(Underlying database - Derby embedded, persistence provider - eclipseLink)
To check generated scripts I set <property name="javax.persistence.schema-generation-target" value="database-and-scripts"/>
And as a result I got it with some 'sequence' table within.
And although ... ERROR 42X05: Table/View 'SEQUENCE' does not exist.
Can somebody help to understand such a weird behavior?
maven dependencies:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.9.1.0</version>
</dependency>
Entity:
import javax.persistence.*;
#Entity
public class Book {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
// getters/setters/constructors
}
main body:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("chapter04PU");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(new Book("Neuromancer"));
tx.commit();
em.close();
emf.close();
persistence-unit:
<persistence-unit name="chapter04PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>Book</class>
<properties>
<!--<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>-->
<property name="javax.persistence.schema-generation-action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation-target" value="database-and-scripts"/>
<property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.scripts.create-target" value="create.sql"/>
<property name="javax.persistence.schema-generation.scripts.drop-target" value="delete.sql"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:derby:chapter04DB;create=true"/>
</properties>
generated script file:
CREATE TABLE BOOK (ID BIGINT NOT NULL, TITLE VARCHAR(255), PRIMARY KEY (ID))
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)
Update
After replacing:
<property name="javax.persistence.schema-generation-action" value="drop-and-create"/>
with:
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
I can 'normally' run app (with exit code 0).
But I still take this weird message while first run (with absent DB).
the second run is clear - no such messages.
Thanks a lot for your suggestion to use <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>!
As for the second problem, the main culprit here is #GeneratedValue(strategy=GenerationType.AUTO) which probably was a default value provided by IDE on entity creation. Given the way org.eclipse.persistence.jpa.PersistenceProvider processes this annotation (leading to the exception about non-existant 'SEQUENCE' table), the simplest solution would be to just use #GeneratedValue(strategy=GenerationType.IDENTITY) instead.
I have unittest to my java project.
My code uses hibernate.
When i run the test using junit - everything passes.
When I run the test using gradle - I get a mapping error:
Caused by: org.hibernate.MappingException: Unknown entity: linqmap.users.interfaces.model.UserRecord
and the class:
#Entity
#Table(name = "users")
public class UserRecord implements Serializable {
private static final long serialVersionUID = 1L;
public static short CLASS_VERSION = 3;
#Transient
public short objectVersion = CLASS_VERSION;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
public long ID;
#Column(name = "user_name")
public String userName;
#Column(name = "email")
public String email;
#Column(name = "full_name") // will be deprecated in the future
public String fullName;
#Column(name = "password")
public String password;
and a config file:
<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_1_0.xsd"
version="1.0">
<persistence-unit name="UsersDB">
<!-- The provider only needs to be set if you use several JPA providers <provider>org.hibernate.ejb.HibernatePersistence</provider> -->
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class, hbm" />
<!-- SQL stdout logging <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/>
<property name="use_sql_comments" value="true"/> -->
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.url" value="dbc:postgresql://localhost:9992/israel" />
what can be missing in gradle?
I think the problem is not really with gradle. It's with the fact that the JPA spec stupidly requires that the classes of the entities are in the same jar/directory as the persistence.xml file. And since Gradle doesn't store the "compiled" resources in the same output directory as the compiled classes, Hibernate doesn't find the mapped entities.
Add this line to your gradle build, and it will probably be fine
sourceSets.main.output.resourcesDir = sourceSets.main.output.classesDir
I have two different java web application than access a shared postgres database for reading and writing.
My first web application in deployed on apache tomcat and my second web application is deployed on jboss.
When one of my two application write a new row on a table of database, the sequence is incremented of 1 and its value is assigned to primary key and row is stored correctly.
When the other application try to write a new row on the same table, the id than was assigned is not synchronized with sequence, and I have exception for duplicate primary key.
In my java class I use this annotation for define my id:
#Id
#SequenceGenerator(name = "my_seq", sequenceName = "my_seq_on_db", allocationSize=1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq")
Long my_id;
this is my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="MyPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/myDatasouce</jta-data-source>
<class>myPackage.myClass</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>