Fernando Sanchez

Ranch Hand
+ Follow
since Jul 09, 2022
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
3
Received in last 30 days
0
Total given
32
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Fernando Sanchez

I guess this must be a basic question,

I'm trying  for learning purpuse, trying to simulate a reace between 8 threads. I'm trying to use a synchronizedList to store the results of every thread so that I could finally show those results in order just by accessing the list sequentially.
But I'm not managing to achieve that.

I have this classes:
1. Race (with main):

2. Result

3. Monitor (with the method writeResult)

4. And Swimmer (with a synchronized block which tries to lock the use of the syncrhonized list):


When I try it not always the results seem to be ordered, for instance:

--------------------------------------------
           TO THE PLATFORMS
--------------------------------------------
Thread on lane: 1 started and paused
Thread on lane: 2 started and paused
Thread on lane: 3 started and paused
Thread on lane: 4 started and paused
Thread on lane: 5 started and paused
Thread on lane: 6 started and paused
Thread on lane: 7 started and paused
Thread on lane: 8 started and paused
--------------------------------------------
Elapsed time:  1 s ...
--------------------------------------------
Elapsed time:  2 s ...
--------------------------------------------
Elapsed time:  3 s ...
--------------------------------------------
Elapsed time:  4 s ...
--------------------------------------------
Elapsed time:  5 s ...
--------------------------------------------
                 READY
--------------------------------------------
Thread on lane: 1 restarted and paused
Thread on lane: 2 restarted and paused
Thread on lane: 3 restarted and paused
Thread on lane: 4 restarted and paused
Thread on lane: 5 restarted and paused
Thread on lane: 6 restarted and paused
Thread on lane: 7 restarted and paused
Thread on lane: 8 restarted and paused
--------------------------------------------
Elapsed time: 00,50 s ...
--------------------------------------------
Elapsed time: 01,00 s ...
--------------------------------------------
Elapsed time: 01,50 s ...
--------------------------------------------
Elapsed time: 02,00 s ...
--------------------------------------------
                  GO!!!
--------------------------------------------
Thread on lane: 1 restarted and swimming
Thread on lane: 2 restarted and swimming
Thread on lane: 3 restarted and swimming
Thread on lane: 4 restarted and swimming
Thread on lane: 5 restarted and swimming
Thread on lane: 6 restarted and swimming
Thread on lane: 7 restarted and swimming
Thread on lane: 8 restarted and swimming
--------------------------------------------
              ARRIVAL
--------------------------------------------
Lane:  6 - Time: 20,95 s
Lane:  1 - Time: 20,99 s
Lane:  7 - Time: 21,02 s
Lane:  5 - Time: 21,29 s
Lane:  2 - Time: 21,73 s
Lane:  8 - Time: 21,19 s
Lane:  4 - Time: 21,21 s
Lane:  3 - Time: 21,73 s
--------------------------------------------



I have also tried making the writeResult method synchronized instead of using a synchronized block:



But the results continues not to be ordered some times:

--------------------------------------------
              ARRIVAL
--------------------------------------------
Lane:  6 - Time: 21,04 s
Lane:  5 - Time: 21,33 s
Lane:  3 - Time: 21,36 s
Lane:  4 - Time: 21,42 s
Lane:  8 - Time: 21,47 s
Lane:  1 - Time: 21,53 s
Lane:  2 - Time: 21,70 s
Lane:  7 - Time: 21,19 s
--------------------------------------------



I guess there must be some issues I'm not understanding.

Paul Clapham wrote:
You shouldn't assume that running a process in multiple threads will automatically run the process faster. It may happen that the threads interfere with each other in some way, or that they cause some problem like running out of resources. Just for example. I notice that your multithreaded version does run faster than the singlethreaded version sometimes, but I have no idea why it sometimes takes much longer. These things can take a long time to investigate.

So far you only output the number of characters processed by each thread. You might find the time each thread takes to run an interesting piece of information.



Thank you again.

Two very diiferent executions after adding time traces:

One really fast:

con hilos
Fich22.txt --> cuenta: 53335200 Tiempo (ms): 303
Fich08.txt --> cuenta: 53335200 Tiempo (ms): 384
Fich21.txt --> cuenta: 53335200 Tiempo (ms): 362
Fich11.txt --> cuenta: 53340805 Tiempo (ms): 399
Fich30.txt --> cuenta: 56676000 Tiempo (ms): 382
Fich03.txt --> cuenta: 53497950 Tiempo (ms): 429
Fich23.txt --> cuenta: 53335200 Tiempo (ms): 367
Fich10.txt --> cuenta: 53381400 Tiempo (ms): 448
Fich06.txt --> cuenta: 70978400 Tiempo (ms): 454
Fich27.txt --> cuenta: 56676000 Tiempo (ms): 426
Fich19.txt --> cuenta: 56676000 Tiempo (ms): 419
Fich14.txt --> cuenta: 53360400 Tiempo (ms): 461
Fich24.txt --> cuenta: 53335200 Tiempo (ms): 434
Fich17.txt --> cuenta: 56659200 Tiempo (ms): 439
Fich25.txt --> cuenta: 53335200 Tiempo (ms): 416
Fich18.txt --> cuenta: 56650800 Tiempo (ms): 453
Fich04.txt --> cuenta: 70978400 Tiempo (ms): 493
Fich15.txt --> cuenta: 56655000 Tiempo (ms): 475
Fich26.txt --> cuenta: 53335200 Tiempo (ms): 450
Fich09.txt --> cuenta: 53410800 Tiempo (ms): 499
Fich16.txt --> cuenta: 56655000 Tiempo (ms): 477
Fich02.txt --> cuenta: 57833400 Tiempo (ms): 516
Fich05.txt --> cuenta: 83310000 Tiempo (ms): 532
Fich29.txt --> cuenta: 109996850 Tiempo (ms): 544
Fich12.txt --> cuenta: 106792200 Tiempo (ms): 580
Fich28.txt --> cuenta: 106670400 Tiempo (ms): 549
Fich20.txt --> cuenta: 109986000 Tiempo (ms): 538
Fich13.txt --> cuenta: 110061600 Tiempo (ms): 584
Fich07.txt --> cuenta: 106681610 Tiempo (ms): 596
Fich01.txt --> cuenta: 110044815 Tiempo (ms): 596
Tiempo: 596 ms



This one is really slow:

con hilos
Fich25.txt --> cuenta: 53335200 Tiempo (ms): 316
Fich11.txt --> cuenta: 53340805 Tiempo (ms): 928
Fich08.txt --> cuenta: 53335200 Tiempo (ms): 966
Fich19.txt --> cuenta: 56676000 Tiempo (ms): 1221
Fich02.txt --> cuenta: 57833400 Tiempo (ms): 3130
Fich30.txt --> cuenta: 56676000 Tiempo (ms): 3786
Fich24.txt --> cuenta: 53335200 Tiempo (ms): 9536
Fich26.txt --> cuenta: 53335200 Tiempo (ms): 9684
Fich22.txt --> cuenta: 53335200 Tiempo (ms): 10461
Fich14.txt --> cuenta: 53360400 Tiempo (ms): 11606
Fich21.txt --> cuenta: 53335200 Tiempo (ms): 13373
Fich18.txt --> cuenta: 56650800 Tiempo (ms): 21601
Fich10.txt --> cuenta: 53381400 Tiempo (ms): 24965
Fich17.txt --> cuenta: 56659200 Tiempo (ms): 25545
Fich15.txt --> cuenta: 56655000 Tiempo (ms): 26892
Fich23.txt --> cuenta: 53335200 Tiempo (ms): 27036
Fich16.txt --> cuenta: 56655000 Tiempo (ms): 27591
Fich04.txt --> cuenta: 70978400 Tiempo (ms): 30947
Fich09.txt --> cuenta: 53410800 Tiempo (ms): 30951
Fich03.txt --> cuenta: 53497950 Tiempo (ms): 34843
Fich06.txt --> cuenta: 70978400 Tiempo (ms): 38185
Fich27.txt --> cuenta: 56676000 Tiempo (ms): 39614
Fich05.txt --> cuenta: 83310000 Tiempo (ms): 48469
Fich01.txt --> cuenta: 110044815 Tiempo (ms): 48973
Fich07.txt --> cuenta: 106681610 Tiempo (ms): 49377
Fich13.txt --> cuenta: 110061600 Tiempo (ms): 52618
Fich20.txt --> cuenta: 109986000 Tiempo (ms): 53745
Fich28.txt --> cuenta: 106670400 Tiempo (ms): 54569
Fich12.txt --> cuenta: 106792200 Tiempo (ms): 55007
Fich29.txt --> cuenta: 109996850 Tiempo (ms): 55014
Tiempo: 55078 ms


Paul Clapham wrote:No, none of that is of any importance. The code you have will terminate after the longest-running thread finishes and no sooner. Think about it -- if Thread 0 is actually the last to finish, then your waiting loop will wait for it to finish and then quickly notice (in essentially zero time) that the others have already finished. This is true regardless of the finishing order of the threads. And the code can't terminate before the longest-running thread does.



Thank you for the explanation, so one conclussion I should get is that the multithread alternative does not mean better performance in this case. Am I wrong?

When I try the single-thread program it always takes about between 2.5 and 2.9 seconds to end.
On the other hand the multithread alternative is very unpredictable ranging from 0.6 to 57.3 seconds. I don't understand why there can be so very different results.
I guess this is a basic question.

I'm trying (just for learning purposes) starting 30 threads to count the number of characters for 30 text files and then check how long it took to finish all of them (instead of counting in all files sequentially from one single thread).

The program seems to work but I'm not convinced that executing join() in the same order in which the threads were started is a good idea since it would be better execute join() when they have really finished since I have no clue have to do it.

This is the program:


And when I try it I get results like this:
con hilos
Fich09.txt --> cuenta: 53410800
Fich23.txt --> cuenta: 53335200
Fich10.txt --> cuenta: 53381400
Fich25.txt --> cuenta: 53335200
Fich22.txt --> cuenta: 53335200
Fich16.txt --> cuenta: 56655000
Fich04.txt --> cuenta: 70978400
Fich21.txt --> cuenta: 53335200
Fich30.txt --> cuenta: 56676000
Fich15.txt --> cuenta: 56655000
Fich27.txt --> cuenta: 56676000
Fich14.txt --> cuenta: 53360400
Fich03.txt --> cuenta: 53497950
Fich19.txt --> cuenta: 56676000
Fich28.txt --> cuenta: 106670400
Fich02.txt --> cuenta: 57833400
Fich06.txt --> cuenta: 70978400
Fich18.txt --> cuenta: 56650800
Fich11.txt --> cuenta: 53340805
Fich05.txt --> cuenta: 83310000
Fich08.txt --> cuenta: 53335200
Fich26.txt --> cuenta: 53335200
Fich17.txt --> cuenta: 56659200
Fich12.txt --> cuenta: 106792200
Fich24.txt --> cuenta: 53335200
Fich20.txt --> cuenta: 109986000
Fich07.txt --> cuenta: 106681610
Fich01.txt --> cuenta: 110044815
Fich13.txt --> cuenta: 110061600
Fich29.txt --> cuenta: 109996850
Tiempo: 1664 ms



Sometimes the time is noticeably shorter than without using threads, but other times is longer. I think the problem is because the wait for join() calls can be random.
Is there a way that threads let the main one know all of them have finished so that it can check when they ended? Or is there a way to execute the join() calls as the threads really end?
In an Oracle db there is a "COUNTRY" UDT which contains a nested table of a different "CITY" UDT (every country can have several cities).

How can I implement a "cities" property in a Java class "Country" (which implements SQLData interface) that could be mapped to "CITY" UDT?


Thank you again.

I think I'd already understood what you are explaining.

I had alredy tried instantiating, modifying, and deleting persistent objects by programming (using save, delete and update methods). And I got surprised I also had the option of inserting, updating, and deleting objects using HQL language (which I had assumed would be a mere query language). I just tried to check those three options but failed to understand how the insert sentence worked. That was the reason I asked for help although I finally got it.

It's good for me knowing from you that these options of the language must be used only for 'bulk' operations.

With regards to using pure SQL sentences from Hibernate however, I read and tried some examples using createNativeQuery method instead of createQuery (which allows pure SQL insert statements which are not permitted using  createQuery).
Thank you very much for the answer, I'll try to follow your advice if I get time for that.

In case I wasn't clear, Empleados already had a @ManyToOne property that corresponded to the Primary Key of their Departmento table Entity object.

The reason why I was not able to execute the HQL insert sentence was because the table NuevosEmpleados from where I tried to "copy" the row did not have a FK to Departamentos table, afther adding that FK and then re-creating the project objects I managed to make this run.


Which seems to succesfully "copy one row" from NuevosEmpleados to Empleados:

INSERTADAS 1 FILAS
87654321Z                Laura             Clemence                 null 4

I'm giving my first steps with Hibernate, I guess this must be a basic HQL syntax question.

I've been able to insert new rows using HQL in a table when all the related object properties are not objects like this:


But I don't know how I could insert a row when the related object has a property which is an object.
These are the properties the object I'm trying to insert using an HQL insert sentence:


Tim Holloway wrote:It appears that you are coding for Legacy Hibernate. I do not recommend this. Legacy Hibernate may go away someday.

For most SQL-based ORM uses, I recommend the Java Persistence Architecture (JPA). JPA is part of the Jakarta EE standard and was part of the JEE standard that preceeded it, so there's a lot of support and documentation on it, and a much stronger audience to keep it alive.

Further, the JBoss Hibernate team were major contributors to the design and creation of the JPA standard, meaning that it is well-adapted to theit intentions. In fact, I'd argue that Hibernate JPA is more "Hibernate" than (Legacy) Hibernate is at this point.



Thank you for the suggestion, I'll research about that and hopefully find a way to begin it with.

Tim Holloway wrote:But aside from that, I believe that there's a specific Duplicate Record Exception that applies when trying to add a record whose primary key matches one already stored, so it wouldn't be a ConstrainViolationException as such. Rather than ask why your code isn't catching the "Constraint Violation", I'd recommend simply catching all Exceptions, printing a Stack Trace and seeing what the actual Exception type was.


The only Hibernate exception I am able to catch when violating the PK is PersistenceException which seems to "wrap" the ConstraintViolationException:

PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement



The reason why I tried to catch ConstraintViolationException is because in the books and other resources I read, they tried to catch it, but it doesn't work for me.
Another thing than surprises me is that the Session's save method does not throw the exeption as I expected, it wasn't until I tried to commit the transaction that it was thrown.
Thanks for the detailed answer. I'm not developing applications with Hibernate, just trying to understand how it works. My goal with these tests was just trying to understand the "hierarchy" of exceptions which could be thrown when violationg database constraints (that is why I simply catched exceptions and showed them).

I tried to try your suggestion forcing the error by inserting again already existing deptarment nº 3, but I found two porblems:

1st: I don't know if I can find the UnitOfWorkException class somewhere so I improvised this:


2nd: HibernateException exceptions are never reached:


when I try this main method none of the HibernateExeption handler is reached:

package exceptionhandlers;

import clases.Departamentos;
import util.HibernateUtil;

public class main {

public static void main(String... args) throws UnitOfWorkException {
var department = new Departamentos(3, "Marketing");
var command = new DepartmentStoreCommand(HibernateUtil.getSessionFactory());
command.storeDepartment(department);
}

}



produces this output:

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1411)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:489)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3303)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2438)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:449)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
at exceptionhandlers.DepartmentStoreCommand.storeDepartment(DepartmentStoreCommand.java:26)
at exceptionhandlers.main.main(main.java:11)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:37)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3375)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3908)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1407)
... 10 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '3' for key 'departamentos.PRIMARY'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
... 22 more



please remove this post, next post is what I really meant

Stephan van Hulst wrote:Why are you catching these exceptions at all?



I'm just giving my first steps with Hibernate and in different examples I have read they tried to catch ConstraintViolationException just in case a constraint was violated after a Session's save, delete, or update action.
Shouldn't I do that? Should I just have a generic Exception handler?
I have seen two things:

1. I was assuming it was the save method which launched the ConstraintViolationException but in fact it is the commit method which launches it
2. I can catch PersistenceException (not ConstraintViolationException)

I wonder if this code would be acceptable:


Which causes this new output:

Vamos insertar una nueva fila en la tabla Departamentos
nov 18, 2022 9:54:59 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1062, SQLState: 23000
nov 18, 2022 9:54:59 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Duplicate entry '3' for key 'departamentos.PRIMARY'
nov 18, 2022 9:54:59 A. M. org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement


I suppose this must be a very basic question.

I relaunch this code which tries to insert an already existing row in a table but the ConstraintViolationException is catched  in the general catch (Exception e) block insted of being catched in the specific catch (ConstraintViolationException e) block as I expected.

I wonder what should I try to catch that specific exception.

My code:


My console output:

Vamos insertar una nueva fila en la tabla Departamentos
nov 18, 2022 1:10:26 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1062, SQLState: 23000
nov 18, 2022 1:10:26 A. M. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Duplicate entry '3' for key 'departamentos.PRIMARY'
nov 18, 2022 1:10:26 A. M. org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
org.hibernate.exception.ConstraintViolationException: could not execute statement