I built an application with Quarkus and I'm using Hibernate with Panache for the models. Everything goes well, the application starts, but when I call a webservice to get a list using Panache functionalities (.listAll()), I get an empty list and I see the following message in the console:
HHH000183: no persistent classes found for query class: from com.myproject.model.TeamEntity
My models are defined with #Entity annotations that should allow Hibernate to find by itself the entity mappings. Here is an example with the Team model:
#Entity
#Table(name = "TEAM")
public class TeamEntity extends PanacheEntityBase {
#Id
#GeneratedValue(strategy = SEQUENCE, generator = "TEAM_SEQ_GEN")
#SequenceGenerator(name = "TEAM_SEQ_GEN", sequenceName = "TEAM_SEQ", allocationSize = 10)
#Column(name = "ID_TEAM", nullable = false)
private int id;
#Column(name = "NAME", nullable = false)
private String name;
...
}
I don't have any persistence.xml file in the project, only the application.properties linked with Quarkus. Here are the relevant properties extracted from mine:
quarkus.datasource.db-kind=oracle
quarkus.datasource.jdbc.url=jdbc:oracle:thin:/#MYWALLET
%dev.quarkus.datasource.jdbc.url=jdbc:oracle:thin:MYUSER/MYPASSWORD#localhost:1521/SAA
quarkus.datasource.jdbc.driver=oracle.jdbc.OracleDriver
quarkus.datasource.jdbc.min-size=2
quarkus.datasource.jdbc.max-size=10
quarkus.datasource.jdbc.new-connection-sql=alter session set current_schema=MYSCHEMA
quarkus.hibernate-orm.dialect=org.hibernate.dialect.Oracle12cDialect
Does someone know where the problem could come from ? Hibernate should detect entities with annotations and use them in queries automatically.
It came out that the problem was on Quarkus Datasource configuration in the application.properties file. More particularly from this specific line to define the schema used at first connection (I have to admit that was not good looking):
quarkus.datasource.jdbc.new-connection-sql=alter session set current_schema=MYSCHEMA
Replacing the line above with the following solved the problem:
quarkus.hibernate-orm.database.default-schema=MYSCHEMA
In conclusion, I think Hibernate cannot find / does not take the entities defined if this property is not defined, maybe because it makes some kind of detection beforehand. That's only a supposition, if someone knows more precisely how Hibernate works for that specific case, I would be very interested !
Related
So I've read tons and tons of posts, forums, question and answers about this topic but I am still quite unsure about what migration means.
Let me first introduce you to my problem.
I have a Spring Boot backend working with MySQL Database with the help of Spring JPA Entities.
Now my problem is the following:
I already have a Spring JPA Entity defined as follows:
#Entity
#Getter
#Setter
public class Blog {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
private String content;
private LocalDateTime createdAt = LocalDateTime.now();
}
After having this entity persisted to the database, I realized that the simple String title wouldn't be enough as it maps to a varchar(255) making my Blog posts couldn't exceed 255 characters.
So I would like to change this in the database without running any custom built SQL scripts to modify the column type in the table.
I have something in mind like I would modify the current JPA Entity as follows:
#Entity
#Getter
#Setter
public class Blog {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
#Lob // <--- Notice the Lob here
private String content;
private LocalDateTime createdAt = LocalDateTime.now();
}
If I am right, the Large Object annotation would mean that in the Database the column type becomes longtext allowing a lot more characters than 255 so my blog posts would fit.
So in short this is how I stumbled upon the topic of Database Migration I am just unsure if that is the thing I need in this situation. Can you please confirm if I am right about this, also can you please suggest possible solutions for this particular problem? I know there is a tool called Liquibase used for migrations which is quite popular. Should I go for it, or is there somthing else I would need?
Thanks in advance for the help.
I trye to use Hibernate Search with elastic search, for full text search.
Simple entitys work correctly but with one i have a troube.
When i setup annotation #FullTextField on a data column i got an error when application starting:
"Hibernate ORM mapping:
type 'ru.search.entities.TestEntity':
path '.data':
failures:
- HSEARCH000135: No default value bridge implementation for type 'java.lang.Object'. Use a custom bridge."
This my entity:
#Entity
#Indexed(index = "test")
#Table(name = "test")
#TypeDef(name = "jsonb", typeClass = Jsonb.class)
public class TestEntity {
#Id
#Column(name = "id")
private UUID Id;
#Column(name = "data")
#Type(type = "jsonb")
private Map<String, Object> data;
//constructor
//getters
//setters
}
Without #FullTextField annotation entity puts correctly in postgres and elastic. Elastic of course do not contain data column.
By default when you annotate a Map with #FullTextField (or any #*Field annotation), Hibernate Search will index the values. In you case, values are of type Object. Hibernate Search doesn't know how to index an Object.
I suspect you want to index arbitrary JSON data. If that's the case, I believe there's a solution for you right in the documentation examples:
Read this section first to get some context on what property bridges are and how you can use them.
Then you can find a (more complicated) example that does almost exactly what you want here.
If that's not what you need, I suggest exploring the documentation:
You can find a list of supported property types here
You can find help on mapping other property types here
I have Spring Boot Application with Web, JPA, H2, Web, Lombok dependency.
I have entities as follows
#NoArgsConstructor
#AllArgsConstructor
#Data
#Entity
#Getter
public class Book {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private Integer pageCount;
#ManyToOne
#JoinColumn(name = "author_id")
private Author author;
}
#NoArgsConstructor
#AllArgsConstructor
#Data
#Entity
#Getter
public class Author {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String firstName;
#Column
private String lastName;
}
I am getting following JSON in repose for the /books REST endpoint
[
{},
{}
]
If I add getters and setters to entity it works fine. How can I get the actual values in response without adding getters setters as I am using #Data annotation
First of all , In spring it is not a good approach to return the entity object directly from a controller to be converted to json. Use the DTO approach so that you will always have a DTO object returned from the controller endpoint. This way you will have more control over the type and structure of data you want to retun from the endpoint.
Read here about the advantages of using a DTO .
Secondly, verify that your tables follow the basic spring jpa naming conventions or is same as the entity class names if not please add the #Table(name="") annotation to specify the table name. Check that data is being populated to your entity classes.
Remove the #Data annotation.
#Data should not be used on JPA Entities as Entity toString, equals, and hashCode methods need to be authored in a very specific manner. See here for details.
After searching a lot and looking on the answers to my question found a solution.
If I run my spring boot app using java -jar from cmd it works fine. But not with IDE so issue was with IDE configuration.
I am using Eclipse IDE
Right Click on your project -> Properties
Then from Properties window
Java Compiler -> Annotation Processing -> Enable Annotation Processing
This option should be checked then annotations gets processed. I followed https://www.baeldung.com/lombok-ide from Tinku's answer on this question.
need to add Lombok plugin in maven or gradle file link How to configure Lombok with maven-compiler-plugin?.
If you are using IDE then need to install Lombok plugin link https://www.baeldung.com/lombok-ide
If you are using Eclipse check to have Lombok installed:
I have the following in my code:
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Long id;
And, I noted when I have the #GeneratedValue it simply does not generate my MySql tables, yet without that annotation it generates the respective tables.
What are the key points I should be checking for ?
This is very tricky,as you might believe that you have define all the properties of hibernate properly and with the addition of #GeneratedValue annotation resulting a SQL Gram-mer error. Yet, I was able to resolve this by exploring the hibernate properties more carefully. Specifically look for the below properties in the hibernate configuration.
property name="hibernateProperties">
hibernate.dialect=${hibernate.dialect}
hibernate.hbm2ddl.auto=create
for the hibernate.dialect --> you should have org.hibernate.dialect.MySQL5InnoDBDialect
yet you might see, it also generates table for -> org.hibernate.dialect.SQLServerDialect in MySQL database, which push you to a conclusion that you have set the hibernate properties properly.
If any of your metadata annotation produces a grammer error, I strongly suggest you to check the hibernate properties
Thanks
We changed the JPA provider from EclipseLink to Hibernate 4.1.3. A problem occured when attempting to persist entity using generated id. This gives the following error:
JdbcSQLException: Column "NEXTVAL" not found; SQL statement: select nextval for SCHEMA.ID_SEQ_GENERATOR
The sequence for the entity looks like the following:
#Id
#SequenceGenerator(name = "ID_GENERATOR", initialValue = 100000, allocationSize = 1, sequenceName = "ID_SEQ_GENERATOR")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_GENERATOR")
#Column(name = "ID", nullable = false)
public Long getId() {
return this.id;
}
I tried changing the 'strategy = GenerationType.IDENTITY', but it had no effect.
Any advice?
I found out that there are different databases used depending on the environment used. The dialect used is (currently) always the same even though it should change depending on the server the code is executed on. (The correct dialect is actually loaded first, but it then gets replaced because of spring decides to use another class annotated with #Configuration. I think that using profiles should get me past this, though still working with this...)
I found this link which helped me to get on right tracks:
http://techmagik.blogspot.fi/2012/07/sequence-support-in-jpa-for-db2-zos.html.html
Discovering that the H2 was used, I changed the SQL to :
"NEXT VALUE FOR " + sequenceName
Which fixed the error
So the actual problem is with loading correct dialect (as 'Luca Basso Ricci' hinted). The dialect is for DB2 (always), when it should be for H2 in some cases. For some reason this problem manifested when the provider was changed so it made it a bit difficult to track right reason.