I have an Enterprise Application, with some JPA 2.1 entities. I'm reaching the database via a registered JNDI Datasource from WebLogic. The JPA implementation is Hibernate 5.2.17. I'm using Spring Data JPA to ease the database access.
The entity in question:
public class PermissionEntity implements Serializable {
private static final long serialVersionUID = -3862680194592486778L;
#Id
#GeneratedValue
private Long id;
#Column(unique = true)
private String permission;
#ManyToMany
private List<RoleEntity> roles;
}
When I'm trying to insert a new entity, I get the following exception from WebLogic: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction.
This error doesn't happen with other entities. Neither in this, nor in other EARs, while in theory, all the configuration is the same.
It might be a constraint violation, or something else.
In order to understand the problem set the following flag on your managed server startup parameters:
-Dweblogic.transaction.allowOverrideSetRollbackReason=true
This way you should get an error stack with some more relevant information on the container transaction failure.
Related
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 !
Versions:
Hibernate-Core: 5.2.5.Final
Hibernate-Search: 5.5.5.Final
Having the following mappings:
#Indexed
#Entity
#Table(name = "scanresult")
public class ScanResult
{
#Id
private ScanResultKey id;
#Field
#Column(name = "name")
private String name;
}
#Embeddable
public class ScanResultKey implements Serializable
{
#ManyToOne
#JoinColumn(name = "eA", referencedColumnName = "id")
private EntityA entA;
//others...
}
I have read in previous posts that this was an issue in Search 4.4 (when having composite id and foreign relations), but this should be fixed in 5.5. So apparently it is my fault. But I can't figure out what could I do wrong
Exception:
org.hibernate.search.exception.SearchException: HSEARCH000135: Unable to guess FieldBridge for id in entities.keys.ScanResultKey
Note: I only need one field(name) to be indexed
Could you please point out what I'm doing wrong?
OK, Since this question got interest near to none, according to view count, here is, briefly, the way I managed (hopefully) to resolve the problem (Please, correct me if you know more)
Verify modules' versions compatibility
According to one of the commenters in this SO question, not all (even latest) versions are compatible with each other. For example:
Hibernate Search 5.5 works with Hibernate ORM 5.0.x and 5.1.x (NOT
with 5.2.x), and with Apache Lucene 5.3.x, 5.4.x and 5.5.x (Not 6.0)
Stated by: Sanne
This is not a fix to this particular problem, but might save from other issues
Create a FieldBridge for Composite Key implementing
TwoWayFieldBridge
public class ScanResultBridge implements TwoWayFieldBridge
Add annotation to Entity Class, specifying the implementation of Bridge
#FieldBridge(impl = ScanResultBridge.class)
private ScanResultKey id;
I am using JPA in my application, and take one model for example:
public class Project {
#Id
private String uuid;
private String name;
.................
#OneToMany(mappedBy = "project", cascade = CascadeType.ALL)
private List<ProjectDetails> details;
}
As shown,there is a one-to-many association between the Project and the ProjectDetail, once a project is fetched, its details will be populated by the jpa provider which is exactly what I want.
However once the authentication is added to the project, the details will be only available for specified users, which means the auto-fetching details is not necessary.
I know I can use the
project.setDetails(null);
to remove the details information for un-authenticated user in the application level. But I wonder if this is a waste of sql resource? So it would be better if I can set the cascade type at runtime.
How do you solve this kind of problem?
By default, since #OneToMany relationships are lazily loaded, you may not necessarily access the getter from your code if the user has not yet been authenticated thereby preventing the relationship from been loaded.
When the entity eventually gets loaded, I think you should just decide on what to do from your application rather than setting the relationship to null.
I made a NamedQuery that works but I have multiple error markers in eclipse. Now my query might not be legal, an answer of so (see comments) told me it wasn't possible to do what I intended to do in jpa. So, since I managed to do it anyway and I don't really have a clue why it works: my question is what are the underlying risks of using this :
query = "SELECT t FROM Thethread t LEFT JOIN FETCH t.threadVotes tv ON tv.user1=:currentUser ORDER BY t.datePosted DESC"
Under on:
JOIN FETCH expressions cannot be defined with an identification
Under :currentUser:
Input parameters can only be used in the WHERE clause or HAVING clause of a query.
I didn't manage to get the result I want without it. Which is :
Get the newest Thethread
Get only the current user vote in its collection.
If you know how to do that, please, be my guest.
The entities are as such :
public class Thethread implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long idthread;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "date_posted")
private Date datePosted;
private int downvotes;
private int upvotes;
// bi-directional many-to-one association to ThreadVote
#OneToMany(mappedBy = "thethread")
private List<ThreadVote> threadVotes;
}
public class ThreadVote implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id_votes_thread")
private int idVotesThread;
private int vote;
// bi-directional many-to-one association to Thethread
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "thread")
private Thethread thethread;
// bi-directional many-to-one association to User
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "from_user")
private User user1;
}
Your query is correct JPQL according to JPA 2.1 (JavaEE 7). Eclipselink supports it and other providers should too, if they support 2.1 version of JPA.
The operator ON with JOIN is new with this latest JPA version, it was not present in neither JPA 2.0 (JavaEE 6) nor in older JPA 1 versions.
Here is more info from EclipseLink wiki. The wiki states that Eclipselink implements ON operator and that it is in draft JPA 2.1. I checked also that it is also in final JPA 2.1 specification - and it is there.
In order to use your query, you just need to ensure that your environment/application server supports JPA 2.1 (e.g. application server should support Java EE 7, such as Glassfish 4 or WildFly 8+)
It is not a problem that your IDE (Eclipse) gives warnings until your query works. Eclipse probably does not support JPA 2.1 syntax or your project must be somehow configured to support JPA 2.1 and not older versions of JPA. Try to look into project properties, under project facets, and ensure you have JPA in version 2.1
#Entity
#Table(name="timesheet")
public class TimeSheet extends HibernateDaoSupport implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="timesheetid")
private int timesheetid;
#Transient
private Employee employeeName;
-
-
-
}
In the above code I use annotations with hibernate to create tables in mysql backend.
Table is not getting created while running this code .
There is no exception in the console.
I have used the similar code prior to create many tables.Now its not working .
Is there anything i am missing ?
Kindly help.
The point of Hibernate is not to create database tables, but to use them. You may ask Hibernate to create the schema for you in development, but that should be used only for quick prototyping, and certaily not on a production database.
See http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#configuration-misc-properties. You must use the hibernate.hbm2ddl.auto property to tell Hibernate to create or update database tables when the session factory is created.