Spring @Scope

in Spring frameworks, sometimes you need to take control of beans scope, in that case you can add AOP jar files which will come if you use BOM, and Context set of dependencies and then easily use the @Scope annotation on beans. Below is a set of bean scope available in Spring:

  • Singleton = only one object in entire Spring container
  • prototype = a new object per every time calling applicationContext.getBean(…)
  • web based bean scope:
    • request // a new object per request – a little bit longer than prototype since that was being called by getbean method every time.
    • session // an object per session and will be renewed whenever we hit the timeout for that session
    • globalsession // an object for entire application

example:


@service("myservice")

@scope("singleton") // this is the default bean scope
//or using this @Scope(ConfirgurableFactoryBean.SCOPE_SINGLETON)

public class MyServiceImple extends MyService{

//....

}

 

 

Advertisements

Testing in Java Part 1 – Basics

Different types of testing:

  1. System test / End to End test normally will be done via QA
  2. Aggregate Test / testing component to make sure the business functionalities with all the dependencies could be done as they supposed to. it took longer than unit test since it has a database to set up and tear down, or clean up some stuff, etc.
  3. Unit test / testing each individual functionality. no dependencies.

 

3 Stages every test case needs to have:

  1.  prepare the environment for testing (preparing any requirement before actually testing the behaviour – it might happen in every method.)
  2. the behaviour to test (the actual function you want to test – if that’s too big, you’re testing a lot of functionalities and if something happened you need a way to find that between that complex tests)
  3. checking the result (Assertions)

making testing in orders might make dependencies between unit tests which don’t have any meaning other than, Aggregate testing instead of testing every individual function.

NOTE: every test methods in your test class, should only test one behaviour, even if preparing and function parts of couple test methods will be similar but and the differences will be in assertion parts, then it might show that you are testing differents parts/ behaviours of the function.

NOTE: Make your test methods names, expressing the behaviour of testing, make sure they expose what you want to test.

NOTE: One test class for one Class object.

NOTE: testing the throwing of an exception in the case of a failure of the application?

<br data-mce-bogus="1">

<strong>@Test(Expected=MyTypeOfException.class)</strong>

&nbsp;

 

 

 

 

Reflection – A Quick WrapUp :)

ok, I talked about reflection in couple posts specifically and indirectly I referred to them in a few others, but just to wrap up, Reflections are very useful and very powerful tool that every developers needed them in their toolbox. now, when you read and practice what I have explained so nfar, you can see the connections between that package with others and also you can see its footprints everywhere in Java frameworks and other utilities.

Reflection generally can be used to retrive the information about every Class Type.

you can load and reload Class definition into memory and you can trace everything inside classes, even inner classes (as I explained in my examples in Reflections)

Also Reflection will be used in Annotation processing behind the scene by JDK.

Also for Serialization, Java itself uses reflection to get the SerialVerUID fields to validate the classes.

to make that easy, I can just tell that wherever you saw something might use Class Type, you can now think of Reflection.

Hbm2DLL.auto

The first thing that we should know about this Hibernate Configuration option is, never ever use that (Hbm2DLL.auto) option in production region. However, it can increase development speed in lower/dev regions, and that’s a good practice for large project that wanted to start from scratch – if they have a standard for database schema, and their methodology is Code-First development, but since there is no guarantee in data integrity for existed database schemas, it’s better and safer to avoid using this option in production region. So for legacy application, DON’T  use this option.

Validate: it won’t change the existed tables, but it validate and make sure the mapping file matches what we already have in database.

update: won’t drop, But it will add if the table is there/

create: create tables that are not in db, and drop the one which is already existed and create them again.

create-drop: like create option but it will drop all the tables it created when the SessionFactory closes.

This feature is useful only for development. Create your POJO classes, and then their mapping and that’s all. Then you can set this item in the hibernate.cfg.xml. Then go to database and export the DDL and put the DDL into your actual production environment.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.password">***********</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/MyDataBaseName</property>
  <property name="hibernate.connection.username">appuser</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.use_sql_comments">true</property>
  <property name="hibernate.hbm2ddl.auto">create</property>
  <property name="hibernate.format_sql">true</property>
  <mapping resource="com/navid/practice/hibernate/User.hbm.xml"/>
  <mapping resource="com/navid/practice/hibernate/Plan.hbm.xml"/>
 </session-factory>
</hibernate-configuration>

Traditional Hibernate Issues (POJO): Part#4: ERROR: Unknown column

if you face “ERROR: Unknown column” exception in middle of Hibernate, check the XML mapping file and make sure the name of the pre-existed database tables are matched with what you have mentioned in the XML mapping file, for example:

Oct 29, 2016 2:09:22 PM org.hibernate.dialect.Dialect 
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Hibernate: /* insert com.navid.practice.hibernate.User */ insert into USERS (NAME, TOTAL) values (?, ?)
Oct 29, 2016 2:09:22 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1054, SQLState: 42S22
Oct 29, 2016 2:09:22 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Unknown column 'NAME' in 'field list'
org.hibernate.exception.SQLGrammarException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2840)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3411)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:623)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:277)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:303)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:674)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:666)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:661)
at com.navid.practice.hibernate.Program.main(Program.java:23)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'NAME' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 22 more

Solution:

in the XML mapping file for the related table as mentioned in the exception , I had:

 <hibernate-mapping>
    <class name="com.navid.practice.hibernate.User" table="USERS">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="total" type="int">
            <column name="TOTAL" />
        </property>
    </class>
</hibernate-mapping>

AHA, now we found the culprit … so update the NAME to USERNAME , the field that we already defined in database side and re-run the application again.

found the issue in the highlighted part and updated it with what I have in the database side for that column. After fixing this issue and running the application, then I had the clean run:

INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Oct 29, 2016 2:13:01 PM org.hibernate.dialect.Dialect 
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Hibernate: /* insert com.navid.practice.hibernate.User */ insert into USERS (USERNAME, TOTAL) values (?, ?)
Oct 29, 2016 2:13:02 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/protein_tracker]

Traditional Hibernate Issues (POJO): Part#3 : can’t find the database:

can’t find the database:

INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
 Oct 29, 2016 2:05:15 PM org.hibernate.dialect.Dialect 
 INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
 Hibernate: /* insert com.navid.practice.hibernate.User */ insert into USERS (NAME, TOTAL) values (?, ?)
 Oct 29, 2016 2:05:15 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
 WARN: SQL Error: 1046, SQLState: 3D000
 Oct 29, 2016 2:05:15 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
 ERROR: No database selected
 org.hibernate.exception.GenericJDBCException: could not execute statement
 at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
 at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
 at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
 at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
 at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
 at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42)
 at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2840)
 at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3411)
 at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
 at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:623)
 at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:277)
 at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258)
 at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:303)
 at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
 at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
 at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
 at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
 at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
 at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
 at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
 at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
 at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
 at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:674)
 at org.hibernate.internal.SessionImpl.save(SessionImpl.java:666)
 at org.hibernate.internal.SessionImpl.save(SessionImpl.java:661)
 at com.navid.practice.hibernate.Program.main(Program.java:23)
 Caused by: java.sql.SQLException: No database selected
 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
 at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
 at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
 at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
 at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
 at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
 at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
 at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
 at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098)
 at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
 at org.hibernate.engine.jdb

Solution:

check the configuration xml file and you have to make sure, the database is mentioned in the url.

jdbc:mysql://localhost:3306/

Mine didn’t have that, so I added.

jdbc:mysql://localhost:3306/MyPersonalDatabaseName

Traditional Hibernate Issues (POJO): Part#1 org.hibernate.MappingException: Unknown entity

Unknown Entity exception might have a verity of reasons and causes, however, when you’re using POJO and XML files, since there is no Entity tags and mismatching between JPA nad Hibernate class tags, the reason of this exception might be a little bit challenging. when you’re using POJO with newer version of Hibernate, the main reason might be related to the way you are initiating SessionFactory.something like below…

 

INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
 org.hibernate.MappingException: Unknown entity: com.navid.practice.hibernate.User
 at org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:620)
 at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1605)
 at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
 at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
 at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
 at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
 at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
 at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
 at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:674)
 at org.hibernate.internal.SessionImpl.save(SessionImpl.java:666)
 at org.hibernate.internal.SessionImpl.save(SessionImpl.java:661)
 at com.navid.practice.hibernate.Program.main(Program.java:23)

the issue was related to the version of Hibernate that I had, 5.x and the code that I wrote for init the SessionFactory:

public class HibernateUtilities {

private static ServiceRegistry svcReg = null;
 private static SessionFactory sessionFactory = null;

static {

try {
 Configuration cfg = new Configuration().configure();

svcReg = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
 sessionFactory = cfg.buildSessionFactory(svcReg);

} catch (HibernateException e) {
 System.out.println("An Error in init the SessionFactory!");
 }

}

Solution:

the issue could be resolved just by changing the SessionFactory creation line …

sessionFactory = cfg.buildSessionFactory();