Question, am currently using hibernate and I was wondering if there was any way to get the value of a lazy loaded entities id without hitting the DB again? For example we currently have an entity called group that has a ManyToOne relationship with another entity Organization.
when we call a simple repository method
groupsRepository.findByUser(id) it returns a list of groups based on given user. The query looks like this
select
groups0_.PersonId as PersonId1_118_1_,
groups0_.GroupId as GroupId2_8_1_,
groups1_.GroupID as GroupID1_74_0_,
groups1_.CreatedAt as CreatedA2_74_0_,
groups1_.CreatedBy as CreatedB3_74_0_,
groups1_.Description as Descript4_74_0_,
groups1_.Name as Name5_74_0_,
groups1_.OrganizationID as Organiza9_74_0_,
groups1_.Role as Role6_74_0_,
groups1_.Status as Status10_74_0_,
groups1_.TouchedAt as TouchedA7_74_0_,
groups1_.TouchedBy as TouchedB8_74_0_
from
Groupsofpeople groups0_
inner join
groups groups1_
on groups0_.GroupId=groups1_.GroupID
where
groups0_.PersonId=?
Later on I need to see if the groups org is equal to another org which I do by comparing the OrganizaitonId's, a value that has already been fetched from the db. But every time I do this I have fetch the org from the db, is there anyway to prevent that so that the org attached to group will be prepopulated with it's id since it is already being fetched anyway? Or is this just a concession I have to make if I am using hibernate?
Related
I have a list of JPA entities , and I want to know automatically the order used to generate Database schema , for example :
if Entity A has an association with Entity B , so Table B must be created before Table A , ( I need to know this order for synchronization purposes)
When you start your application , hibernate has a behavior to check the existing schemas (weather or not they persist or not). If the schemas are missing you should see hibernate Logging meta data messages such as (Table Found *table name *) for each and every table. I think that is what you are looking for . It generates all metadata info every time it scans your entity like table found , table created, table not found.
I've two entities: User and UserGroup. Relation between them is #ManyToMany and I'm using envers for auditing these entities, class level #Audited annotation is placed on both of them. However, when I try to execute this query:
AuditReader reader = AuditReaderFactory.get(em);
AuditQuery query = reader.createQuery().forRevisionsOfEntity(User.class, false, true);
Returnted user entities have "org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy" collections of user groups with size equal to zero. Calling size() method on these list proxies doesn't initialize them. Any help will be appreciated.
The problem was the following: I started auditing of entities when there already were users and usergroups in the database. Let's say I was modifying some user's groups. This modification caused in addition of corresponding rows in User_AUD and User_UserGroup_AUD tables, but UserGroup_AUD table was still empty. Later when I was querying for revisions of User entity, it wasn't able to find related UserGroup entities since there was no record in UserGroup_AUD table about those user groups.
I have an appengine backend for an android app.
In this I want to retrieve a number of entities based on their 'id'
I've tried using a WHERE IN query for this as follows.
"select from MyEntity as MyEntity where id IN ('4538783999459328')"
The datastore contains a MyEntity with key that contains id as 4538783999459328.
But the result set is blank. I have tried using other field names of the entity and it works, but am not able to filter with the id.
Is there any other way of doing this?
I'm using Appengine JAVA.
I don't want to use EntityManager.find() because I want to look up more than one id.
Two things:
you have to use __key__ instead of id in queries
there is a special Data type for Entity id - Key('EntityName', ID)
So, your query should look like this:
select * from MyEntity where __key__ in (Key('MyEntity', 4538783999459328))
Also, take a look at GQL doc: https://cloud.google.com/appengine/docs/python/datastore/gqlreference
All the frameworks that implements datastore have a choice of get entities by a list of IDs (Key), or how the above post with GQL is the same.
I am trying to search a view based on given criteria. This view has a few fields for multiple different entities in my application that a user may want to search for.
When I enter the name of an entity I want to search for, I add a restriction for the name field to the detached criteria before calling .findByCriteria(). This causes .findByCriteria() to retrieve a list of results with the name I am looking for.
Also, when I look through my log, I can see hibernate calling a select statment.
I have now added another entity to my view, with a few searchable fields. When I try to search for a field related to this new entity, I get an exception in my log.
When I look through my log with the exception, I can see hibernate calling a select statment with an update statement right after the select (I am not trying to update a record, just retrieve it in a list).
So why is hibernate calling an update when I am calling .findByCriteria() for my new entity?
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
SQL that is executed:
Hibernate:
select
*
from
( select
this_.SEARCH_ID as SEARCH1_35_0_,
this_.ST_NM as ST24_35_0_
from
SEARCH_RESULT this_
where
this_.LOAN_TYPE=? )
where
rownum <= ?
DEBUG 2012-03-21 11:37:19,332 142195 (http-8181-3:org.springframework.orm.hibernate3.HibernateTemplate):
[org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:389)]
Eagerly flushing Hibernate session
DEBUG 2012-03-21 11:37:19,384 142247 (http-8181-3:org.hibernate.SQL):
[org.hibernate.jdbc.util.SQLStatementLogger.logStatement(SQLStatementLogger.java:111)]
update
SEARCH_RESULT
set
ADDR_LINE1=?,
ASSGND_REGION=?,
BASE_DEAL_ID=?,
ST_NM=?
where
SEARCH_ID=?
There is probably an update happening because Hibernate is set up to do an autoflush before executing the queries, so if the persistence context thinks it has dirty data, it will try to update it. Without seeing the code I can't be sure, but I'd guess that even though search_result is a view, your corresponding Java object is annotated on the getters and the object has matching setters. Hibernate doesn't make a distinction between tables and views, and if you call a setter, Hibernate will assume that it has data changes to update.
You can tweak how you build your Java objects for views by adding the #Immutable annotation (or hibernate.#Entity(mutable = false) depending on which version you're using. This should be enough to indicate to Hibernate to not flush changes. You can also annotate the fields directly and get rid of your setters so that consumers of the SearchResult object know that it's read only.
I'm currently learning Hibernate, and I've stumbled into this issue:
I have defined 3 entities: User, Module, Permission. Both user and module have a one-to-many relationship with Permission, so that Permission's composite id consists of idUser and idModule. The user class has a property that is a set of Permission's and it is appropriately annotated with #OneToMany, cascade=CascadeType.ALL, etc.
Now, I generated the classes with MyEclipse's reverse engineering feature. The id of permission was created as a separate class that has an idUser and idModule property. I thought I could create a User, add some new permissions to it, and thus saving the user would cascade the operation, and permissions would be saved automatically. This is true except that the operation causes an exception. I run the following code:
Permission p = new Permission();
p.setId(new PermissionId(null, module.getId());
user.getPermissions().add(p);
session.save(user);
The problem I have is that, even though the SQL is being generated correctly (first saves User, then Permission), I get an error from the database driver (Firebird) which states that it can't insert a null value for idUser, which is true, but shouldn't hibernate be passing the newly created user id to the second query?
This particular scenario feels very counter-intuitive to me since I'm inclined to pass a null id to the Permission object since it is new and I want it to be created, but on other hand, I have to set the idModule property since the module already exists, so I don't really understand how an operation like this is supposed to work.
Does anyone know what I'm doing wrong? Thanks
You need to specify a cascade action for Hibernate to perform when you save a User with an attached transient (meaning not-yet-saved) Permission.
By the way, you might want to consider using a different ID strategy for the Permission object, such as a generated ID value - how can the primary key of the permission row in the database contain a null value?