Does Datanucleus JPA have support for MongoDB
For example:
entityManager.createNativeQuery("db.Movie.find()");
It makes little sense to do what you're doing. By that I mean you can gain access to the underlying MongoDB "DB" object (that JPA is using) and do things using the native MongoDB API, rather than expecting DataNucleus to invent some artificial query language layered on top of it (this string db.BLAH.find() doesn't exist in the MongoDB native API, instead you do db.getCollection("BLAH") and then impose constraints etc and finally call find() on it). Instead you could try (something like) this
import org.datanucleus.ExecutionContext;
import org.datanucleus.store.NucleusConnection;
ExecutionContext ec = em.unwrap(ExecutionContext.class);
NucleusConnection conn = ec.getStoreManager().getNucleusConnection(ec);
DB db = (DB)conn.getNativeConnection();
Thereafter you have the DB object to use, and after use you should call
conn.close();
to hand it back to JPA (DataNucleus).
Related
This question already has answers here:
Spring Data JPA Update #Query not updating?
(5 answers)
Closed 2 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Let's suppose to have this situation:
We have Spring Data configured in the standard way, there is a Respository object, an Entity object and all works well.
Now for some complex motivations I have to use EntityManager (or JdbcTemplate, whatever is at a lower level than Spring Data) directly to update the table associated to my Entity, with a native SQL query. So, I'm not using Entity object, but simply doing a database update manually on the table I use as entity (it's more correct to say the table from which I get values, see next rows).
The reason is that I had to bind my spring-data Entity to a MySQL view that makes UNION of multiple tables, not directly to the table I need to update.
What happens is:
In a functional test, I call the "manual" update method (on table from which the MySQL view is created) as previously described (through entity-manager) and if I make a simple Respository.findOne(objectId), I get the old object (not updated one). I have to call Entitymanager.refresh(object) to get the updated object.
Why?
Is there a way to "synchronize" (out of the box) objects (or force some refresh) in spring-data? Or am I asking for a miracle?
I'm not ironical, but maybe I'm not so expert, maybe (or probably) is my ignorance. If so please explain me why and (if you want) share some advanced knowledge about this amazing framework.
If I make a simple Respository.findOne(objectId) I get old object (not
updated one). I've to call Entitymanager.refresh(object) to get
updated object.
Why?
The first-level cache is active for the duration of a session. Any object entity previously retrieved in the context of a session will be retrieved from the first-level cache unless there is reason to go back to the database.
Is there a reason to go back to the database after your SQL update? Well, as the book Pro JPA 2 notes (p199) regarding bulk update statements (either via JPQL or SQL):
The first issue for developers to consider when using these [bulk update] statements
is that the persistence context is not updated to reflect the results
of the operation. Bulk operations are issued as SQL against the
database, bypassing the in-memory structures of the persistence
context.
which is what you are seeing. That is why you need to call refresh to force the entity to be reloaded from the database as the persistence context is not aware of any potential modifications.
The book also notes the following about using Native SQL statements (rather than JPQL bulk update):
■ CAUTION Native SQL update and delete operations should not be
executed on tables mapped by an entity. The JP QL operations tell the
provider what cached entity state must be invalidated in order to
remain consistent with the database. Native SQL operations bypass such
checks and can quickly lead to situations where the inmemory cache is
out of date with respect to the database.
Essentially then, should you have a 2nd level cache configured then updating any entity currently in the cache via a native SQL statement is likely to result in stale data in the cache.
In Spring Boot JpaRepository:
If our modifying query changes entities contained in the persistence context, then this context becomes outdated.
In order to fetch the entities from the database with latest record.
Use #Modifying(clearAutomatically = true)
#Modifying annotation has clearAutomatically attribute which defines whether it should clear the underlying persistence context after executing the modifying query.
Example:
#Modifying(clearAutomatically = true)
#Query("UPDATE NetworkEntity n SET n.network_status = :network_status WHERE n.network_id = :network_id")
int expireNetwork(#Param("network_id") Integer network_id, #Param("network_status") String network_status);
Based on the way you described your usage, fetching from the repo should retrieve the updated object without the need to refresh the object as long as the method which used the entity manager to merge has #transactional
here's a sample test
#DirtiesContext(classMode = ClassMode.AFTER_CLASS)
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ApplicationConfig.class)
#EnableJpaRepositories(basePackages = "com.foo")
public class SampleSegmentTest {
#Resource
SampleJpaRepository segmentJpaRepository;
#PersistenceContext
private EntityManager entityManager;
#Transactional
#Test
public void test() {
Segment segment = new Segment();
ReflectionTestUtils.setField(segment, "value", "foo");
ReflectionTestUtils.setField(segment, "description", "bar");
segmentJpaRepository.save(segment);
assertNotNull(segment.getId());
assertEquals("foo", segment.getValue());
assertEquals("bar",segment.getDescription());
ReflectionTestUtils.setField(segment, "value", "foo2");
entityManager.merge(segment);
Segment updatedSegment = segmentJpaRepository.findOne(segment.getId());
assertEquals("foo2", updatedSegment.getValue());
}
}
We use Hibernate and annotations to map our db and entities. But for some data tables I don't want entity classes (Because these table names and all are keep changing) so that the application will be more dynamic
So is it possible using hibernate to load data from a table without a entity class?
If so how?
Hibernate provides a way to execute SQL query and to map it to an entity or any class : native sql queries.
Use plain JDBC. I'm not sure what you mean by "table names and all are keep changing" but it sounds like a bad idea to me.
What you could do is create the sql query using string concatenation then use plain JDBC to execute it. That way you can keep table names dynamic.
If Persistence class won't be used, then the data encapsulation won't occur thus data can be accessed directly.
Hibernate Queries interact with the POJO class to fetch data.
Query, Criteria, HQL all the classes use the POJO for fetching data.
Hibernate Framework was mainly designed for the ORM Mapping.
Thus without POJO class, not possible to interact with the database.
Thus using JDBC connection would be the option left.
Use Dynamic models introduced in Hibernate 5 version - 5.4.0.Final
Hibernate Dynamic Models
To achieve this you will need HBM files created.
Session s = openSession();
Transaction tx = s.beginTransaction();
Session s = openSession();
// Create a customer
Map david = new HashMap();
david.put("name", "David");
// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");
// Link both
david.put("organization", foobar);
// Save both
s.save("Customer", david);
s.save("Organization", foobar);
tx.commit();
s.close();
Here Customer & Organization are table names
Organization is Parent of Customer.
Click on the above link for more details
I'm using Spring and JDBC template to manage database access, but build the actual SQL queries using JOOQ. For instance, one DAO may look like the following:
public List<DrupalTaxonomyLocationTerm> getLocations(String value, String language) throws DataAccessException {
DSLContext ctx = DSL.using(getJdbcTemplate().getDataSource(), SQLDialect.MYSQL);
SelectQuery q = ctx.selectQuery();
q.addSelect(field("entity_id").as("id"),);
q.addFrom(table("entity").as("e"));
[...]
}
As you can see from the above, I'm building and executing queries using JOOQ. Does Spring still take care of closing the ResultSet I get back from JOOQ, or do I somehow "bypass" Spring when I access the data source directly and pass the data source on to JOOQ?
Spring doesn't do anything with the objects generated from your DataSource, i.e. Connection, PreparedStatement, ResultSet. From a Spring (or generally from a DataSource perspective), you have to do that yourself.
However, jOOQ will always:
close Connection objects obtained from a DataSource. This is documented in jOOQ's DataSourceConnectionProvider
close PreparedStatement objects right after executing them - unless you explicitly tell jOOQ to keep an open reference through Query.keepStatement()
close ResultSet objects right after consuming them through any ResultQuery.fetchXXX() method - unless you explicitly want to keep an open Cursor with ResultQuery.fetchLazy()
By design, jOOQ inverses JDBC's default behaviour of keeping all resources open and having users tediously close them explicitly. jOOQ closes all resources eagerly (which is what people do 95% of the time) and allows you to explicitly keep resources open where this is useful for performance reasons.
See this page of the jOOQ manual for differences between jOOQ and JDBC.
I use the org.jooq.util.DefaultGenerator during the build process to generate jOOQ classes to represent my database schema.
While the application runs, the schema is expected to change without the application knowing about it. Such changes may or may not be compatible with the already generated code.
How can I detect in runtime whether the generated code is still valid against a certain schema?
I'm looking for something like boolean stillValid = new SchemaValidator(existingGeneratedCodePath, jdbcUrl, jdbcProps).validate();
A jOOQ 3.0 solution using org.jooq.Meta
In the upcoming jOOQ 3.0, JDBC's DatabaseMetaData can be accessed in a "jOOQ way" through a new org.jooq.Meta object (implemented with feature request #1968). This object provides access to various objects of these types:
org.jooq.Catalog
org.jooq.Schema
org.jooq.Table
org.jooq.Field
org.jooq.DataType
These could be compared to your generated classes, e.g.
MY_SCHEMA.getTables().equals(create.meta().getTables())
A jOOQ 2.x solution using JDBC DatabaseMetaData
The above solution can be implemented manually, querying the Connection.getMetaData(). It'll be a bit more work, of course
A trick querying all the tables
Another simple solution would be to query all the generated tables like this:
List<Table<?>> invalidTables = new ArrayList<>();
for (Table<?> table : MY_SCHEMA.getTables()) {
try {
create.selectFrom(table).where(Factory.falseCondition()).fetch();
}
// If table names / column names change, the above query would fail
catch (DataAccessException e) {
invalidTables.add(table);
}
}
This trick would allow to detect if increments are compatible
I have to create a query in our backend application using the parameters obtained from the client. Consider this diagram:
I have entities (Type field), those entities' fields (Parameter), a relation, a value and an operand. So in sql terms the table above translates to this:
... WHERE Item.reach_complience = ”<1%”
and Item.technical.type = ”RES”
and Item.technical.value <= ”1k”
and Item.technical.value >= ”4K7”
and (Item.technical.footprint = ”RC0603” or Item.technical.footprint = ”RC0805”)
and Item.classification.incurrent_handling = ”prefered-to-use”
I really don't want to reinvent the weel here, so my question is:
Is there a Criteria factory libarary which uses JPA or more specifically Hibernate or is there some 3rd party library which can be used to create criteria queries? We are using Eclipse RCP on the frontend and data arrives to the backend (Spring) through an Apache Cxf service. I wish to write maintainable using JPA's query syntax.
Yes. I think ISearch is the best: http://code.google.com/p/hibernate-generic-dao/wiki/Search