Get all table names set up in SessionFactory - java

Is there a way to retrieve the name of all tables that are managed by the SessionFactory? For instance, all the tables that were added via AnnotationConfiguration.addAnnotatedClass(...))?

Here is howto getting one tableName with getClassMetadata
ClassMetadata cm = sessionFactory.GetClassMetadata(className);
AbstractEntityPersister aep = (AbstractEntityPersister) cm;
String tableName = aep.getTableName();
[EDIT] : you can find all by calling getAllClassMetadata() and find all table names like that
Map m = sessionFactory.GetAllClassMetadata();
/* iterate map*/
AbstractEntityPersister aep = m.get(/*key (className)*/)
String tableName = aep.getTableName();

If you are using JPA instead of direct dependency on hibernate., following code should help in getting all table names
private List<String> getAllTables() {
List<String> tableNames = new ArrayList<>();
Session session = entityManager.unwrap(Session.class);
SessionFactory sessionFactory = session.getSessionFactory();
Map<String, ClassMetadata> map = (Map<String, ClassMetadata>) sessionFactory.getAllClassMetadata();
for(String entityName : map.keySet()){
SessionFactoryImpl sfImpl = (SessionFactoryImpl) sessionFactory;
String tableName = ((AbstractEntityPersister)sfImpl.getEntityPersister(entityName)).getTableName();
tableNames.add(tableName);
}
return tableNames;
}

sessionFactory.GetClassMetadata(className);
is deprecated. Use
Metamodel metamodel = entityManager.getMetamodel();
Set<EntityType<?>> entities = metamodel.getEntities();
entities.forEach(e -> {
System.out.println(e.getName());
});
Your can also get metamodel from SessionFactory

You can try using native sql queries.
session.createSQLQuery("SELECT * FROM user_tables").list();
which gives list of tables owned by loggedin user or else you can use 'all_tables' or 'dba_tables' for all the tables for oracle database.If mysql db is used then replace the query with "SHOW TABLES"

Related

Get entity by email in hibernate

I am trying to get the user from his email , the email is unique in the database.
I write this code :
session.beginTransaction();
User user = (User) session.createQuery("select * from `user` where email = '"+email+"'");
session.getTransaction().commit();
Is this code right ? or there is some function in hibernate to get entity by column value ?
I see two problems with your current code. First, you appear to be running a native SQL query, not HQL (or JPQL). Second, your query is built using string concatenation, leaving it prone to attack by SQL injection
Consider the following code:
Query query = session.createQuery("from User u where u.email = :email ");
query.setParameter("email", email);
List list = query.list();
Without writting any SQL:
public static Person getPersonByEmail(String email) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Person> cr = cb.createQuery(Person.class);
Root<Person> root = cr.from(Person.class);
cr.select(root).where(cb.equal(root.get("email"), email)); //here you pass a class field, not a table column (in this example they are called the same)
Query<Person> query = session.createQuery(cr);
query.setMaxResults(1);
List<Person> result = query.getResultList();
session.close();
return result.get(0);
}
example of use:
public static void main(String[] args) {
Person person = getPersonByEmail("test#mail.com");
System.out.println(person.getEmail()); //test#mail.com
}

Apache Ignite : How to list all tables and all Caches

Is there any way to list all tables present in a specific Cache and list all caches present on a Apache Ignite Server?
----------------------------------UPDATED--------------------------
Hi,
I am running following code to know Cache name and list all tables present in my cache. This program list outs all cache name present on server. However table listing is printed as blank collection. Meanwhile SQL query present in example is working fine.
public static void main(String[] args) throws Exception {
System.out.println("Run Spring example!!");
Ignition.setClientMode(true);
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIncludeEventTypes( EVTS_CACHE);
cfg.setPeerClassLoadingEnabled(true);
TcpDiscoveryMulticastIpFinder discoveryMulticastIpFinder = new TcpDiscoveryMulticastIpFinder();
Set<String> set = new HashSet<>();
set.add("hostname:47500..47509");
discoveryMulticastIpFinder.setAddresses(set);
TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
discoverySpi.setIpFinder(discoveryMulticastIpFinder);
cfg.setDiscoverySpi(discoverySpi);
cfg.setPeerClassLoadingEnabled(true);
cfg.setIncludeEventTypes(EVTS_CACHE);
Ignite ignite = Ignition.start(cfg);
System.out.println("All Available Cache on server : "+ignite.cacheNames());
CacheConfiguration<String, BinaryObject> cacheConfiguration = new CacheConfiguration<>(CACHE_NAME);
Collection<QueryEntity> entities = cacheConfiguration.getQueryEntities();
System.out.println("All available tables in cache : "+entities);
cacheConfiguration.setIndexedTypes(String.class, BinaryObject.class);
//cacheConfiguration.setCacheMode(CacheMode.PARTITIONED);
IgniteCache<String, BinaryObject> cache = ignite.getOrCreateCache(cacheConfiguration).withKeepBinary();
System.out.println();
QueryCursor<List<?>> query = cache.query(new SqlFieldsQuery("select Field1 from table1 where Field1='TEST'"));
List<List<?>> all = query.getAll();
for (List<?> l : all) {
System.out.println(l);
}
}
Get all cache names: Ignite.cacheNames(). Then use Ignite.cache(String) to get the cache instance.
Get SQL tables:
CacheConfiguration ccfg = cache.getConfiguration(CacheConfiguration.class);
Collection<QueryEntity> entities = ccfg.getQueryEntities();
Each query entity represents a table.
You can read using h2 query.
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA is the cache name
ClientConfiguration cfg = new ClientConfiguration().setAddresses(host+":"+port).
setUserName(username).setUserPassword(pwd);
private static IgniteClient igniteClient = Ignition.startClient(cfg);
private static ClientCache<Integer, String>
cache=igniteClient.getOrCreateCache(cacheName);
QueryCursor<List<?>> cursor =cache.query(new SqlFieldsQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='"+cacheName+"'"));
for (List<?> row : cursor) {
System.out.println(row.get(0));
}
You can get all cache names using Ignite.cacheNames(). In order to get all table names you can use SHOW TABLES command:
QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery("SHOW TABLES FROM \""+CACHE_NAME+"\""));
for (List<?> row : cursor) {
System.out.println(row.get(0));
}
More details about the SHOW command you can find here: http://www.h2database.com/html/grammar.html#show

JPA reuse some "previous" JDBC login credentials

I don't know if this is really a bug ... it seems that something remains "open".
I'm using EclipseLink 2.5 with com.microsoft.sqlserver.jdbc.SQLServerDriver.
In the second call at the createEntityManagerFactory method a wrong password is ignored and everything works as well ...
Do I have to reset or clean some kind of Connection or Session Object ?
String userId = "sa";
String psw = "rightPassword";
Map<String, Object> paramsConnect = new HashMap<String, Object>();
paramsConnect.put("javax.persistence.jdbc.user", userId);
paramsConnect.put("javax.persistence.jdbc.password", psw);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PU", paramsConnect);
EntityManager em = emf.createEntityManager();
Query q = em.createNativeQuery("SELECT * FROM Tab1");
List<Object[]> rows = q.getResultList();
System.err.println(rows.get(0));
em.clear();
em.close();
emf.close();
psw = "wrongPassword";
EntityManagerFactory emf1 = Persistence.createEntityManagerFactory("PU", paramsConnect);
EntityManager em1 = emf1.createEntityManager();
Query q1 = em1.createNativeQuery("SELECT * FROM Tab2");
List<Object[]> rows1 = q1.getResultList();
System.err.println(rows1.get(0));
If you want to change the value with key 'javax.persistence.jdbc.password' in your HashMap you need to change the line:
psw = "wrongPassword";
with the line:
paramsConnect.put("javax.persistence.jdbc.password", "wrongPassword");
The method put will replace the value of an existing key and will create it if doesn't exist.

Java Hibernate HQL to Hibernate Criteria

I have a class that uses Hibernate HQL queries. I would like to change these into Hibernate Criteria queries.
However, Hibernate Criteria is a lot harder for me to understand than HQL, even with tutorials. Could someone show me how one of the queries would look like using Hibernate Criteria/Filters?
Configuration configuration = new Configuration();
configuration.configure().setProperty("hibernate.show_sql", "false");
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(serviceRegistry);
Session session =sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from TABLENAME WHERE IDObject1= :idObjectA" +
"AND IDObject2= :idObjectB AND IDSettingOption = :idSettingOption");
query.setParameter("idObjectA", idObjectB);
query.setParameter("idObjectB", idObjectB);
query.setParameter("idSettingOption", idSettingOption);
List results = query.list();
Thanks in advance!
Criteria criteria = session.createCriteria( TABLENAME.class );
criteria.add( Restrictions.eq( "IDObject1" , idObjectB) );
criteria.add( Restrictions.eq( "IDObject2" , idObjectB) );
criteria.add( Restrictions.eq( "IDSettingOption" ,idSettingOption) );
List results = criteria.list();
Here you can read about Criteria API, it has a lot of examples:
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html
List results = session.createCriteria(Entity.class)
.add(Restrictions.eq("IDObject1", idObjectA))
.add(Restrictions.eq("IDObject2", idObjectB))
.add(Restrictions.eq("idSettingOption", idSettingOption))
.list();

JPA / Hibernate: CriteriaBuilder - How to create query using relationship object?

I have the following four tables:
SCHEDULE_REQUEST TABLE:
ID,
APPLICATION_ID (FK)
APPLICATION TABLE:
ID,
CODE
USER_APPLICATION TABLE:
APPLICATION_ID (FK),
USER_ID (FK)
USER TABLE:
ID,
NAME
Now I wanted to create a CriteriaBuilder where condition is to select ScheduleRequests for specified user Ids.
I have the following codes:
List<User> usersList = getSelectedUsers(); // userList contains users I wanted to select
CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder();
CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class);
Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class);
criteria = criteria.select(scheduleRequest);
ParameterExpression<User> usersIdsParam = null;
if (usersList != null) {
usersIdsParam = builder.parameter(User.class);
params.add(builder.equal(scheduleRequest.get("application.userApplications.user"), usersIdsParam));
}
criteria = criteria.where(params.toArray(new Predicate[0]));
TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria);
// Compile Time Error here:
// The method setParameter(Parameter<T>, T) in the type TypedQuery<ScheduleRequest> is not
// applicable for the arguments (ParameterExpression<User>, List<User>)
query.setParameter(usersIdsParam, usersList);
return query.getResultList();
Can you please help me how to pass query filter to a relationship object?
I think what I did in "application.userApplications.user" is wrong?
Please really need help.
Thank you in advance!
Using the canonical Metamodel and a couple of joins, it should work. Try if you get some hints from the following pseudo-code (not tested):
...
Predicate predicate = cb.disjunction();
if (usersList != null) {
ListJoin<ScheduleRequest, Application> applications = scheduleRequest.join(ScheduleRequest_.applications);
ListJoin<Application, UserApplication> userApplications = applications.join(Application_.userApplications);
Join<UserApplication, User> user = userApplications.join(UserApplication_.userId);
for (String userName : usersList) {
predicate = builder.or(predicate, builder.equal(user.get(User_.name), userName));
}
}
criteria.where(predicate);
...
In order to understand Criteria Queries, have a look at these tutorials:
http://www.ibm.com/developerworks/java/library/j-typesafejpa/
http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html
The second link should also guide you on how to use Metamodel classes, that should be built automatically by the compiler / IDE.

Categories