I have configured two datasources in my Spring/MyBatis application. I don't get any error while startup (its reading the Mapper XML and interface). But when invoking the method, its throwing the following exception:
MyBatisSystemException: SqlSession operation; nested exception is java.lang.IllegalArgumentException: selectByPrimaryKey is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries)
It doesn't quite clearly say the cause for ambiguity.
Related
I've an entity with property name qYear. I tried creating a findByIdAndQYear method in repository but that did not work. I ran into IllegalArgumentException: Unable to locate Attribute with the the given name [QYear] on this ManagedType).
However findByIdAndqYear works. Any idea how single letter abbreviations like this are expanded please?
Spring Data (not just the JPA module) base this on the Java Bean Specification.
In order to avoid misinterpretation of the specification this is actually implemented using [java.beans.Introspector][1].
See also https://jira.spring.io/browse/DATACMNS-1589
I've seen a lot of similar questions but they are usually just tangential to mine.
Here is my code.
#Override //class implements interface
//can also add "rollbackFor = OutOfMemoryError.class" here, to no avail
#Transactional(noRollbackFor = IllegalArgumentException.class)
public ReportTemplate getByCode(final String code)
//throws IllegalArgumentException - see question text
{
if(code == null) {
throw new IllegalArgumentException("ss");
}
}
Consumer (non-transactional) calls this method via autowired interface.
Despite noRollbackFor the transaction (consisting of this method alone) gets rolled back.
Ok I understand people who say "by default it's rollbackFor any unchecked, so since the default is not overridden, that rule still applies". But that should not be true, because that would mean noRollbackFor is useless :) We can try specify rollbackFor as in the comment above, in a hope it will cancel "default" rollbackFor - but this does not help: rollback still happens; looks like this setting is simply added to "default". Worst of all, I can't find a precise specification on how it should work, when noRollbackFor and rollbackFor are covering the same descendant exception (like in my case, RuntimeException vs IllegalArgumentException, who wins?).
Well, I was able to find but one official clarification and it says "the strongest matching rule wins" - but this seems to not be universally corrent, as in my case. Also, for some reason they are overly specific: they say no-rollback-for="InstrumentNotFoundException" means, literally, "any exception other than an InstrumentNotFoundException" would be rolled back (but what about InstrumentNotFoundException's descendants?) And anyway it's greatly outdated: 2.5.x, and newer documentation just says something like "rollbackFor lists exceptions to be rolled back, and noRollbackFor lists exceptions not to be", in a quite contradictory manner, I'd say.
What is even more interesting, the code above stops rolling back if I specify IllegalArgumentException in its "throws" clause. Yes, I don't have to, since its unchecked - but if I do, noRollbackFor finally seems to notice it and behave properly! Does anyone know what manual says this should happen? Or maybe it's a bug?
UPDATE Here are spring transaction logs (in my actual code YargReportTemplateDao$TemplateNotFoundException there is everywhere instead of IllegalArgumentException)
1) with "throws"
[qtp22373939-44] TRACE org.springframework.transaction.interceptor.TransactionInterceptor - Completing transaction for [ru.it.p321.dao.YargReportTemplateDaoImpl.getByCode] after exception: ru.it.p321.dao.YargReportTemplateDaoImpl$1: Yarg template was not found for given code: ITORG_REJECT_NOTIFICATION
[pool-28-thread-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager - Initiating transaction commit
[qtp22373939-44] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - Applying rules to determine whether transaction should rollback on ru.it.p321.dao.YargReportTemplateDaoImpl$1: Yarg template was not found for given code: ITORG_REJECT_NOTIFICATION
[qtp22373939-44] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - Winning rollback rule is: NoRollbackRuleAttribute with pattern [ru.it.p321.dao.YargReportTemplateDao$TemplateNotFoundException]
2) without "throws
[qtp21176461-48] TRACE org.springframework.transaction.interceptor.TransactionInterceptor - Completing transaction for [ru.it.p321.dao.YargReportTemplateDaoImpl.getByCode] after exception: org.springframework.dao.InvalidDataAccessApiUsageException: Yarg template was not found for given code: ITORG_REJECT_NOTIFICATION; nested exception is ru.it.p321.dao.YargReportTemplateDaoImpl$1: Yarg template was not found for given code: ITORG_REJECT_NOTIFICATION
[qtp21176461-48] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - Applying rules to determine whether transaction should rollback on org.springframework.dao.InvalidDataAccessApiUsageException: Yarg template was not found for given code: ITORG_REJECT_NOTIFICATION; nested exception is ru.it.p321.dao.YargReportTemplateDaoImpl$1: Yarg template was not found for given code: ITORG_REJECT_NOTIFICATION
[qtp21176461-48] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - Winning rollback rule is: null
[qtp21176461-48] TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - No relevant rollback rule found: applying default rules
The behavior you see has nothing to do with transaction handling but with exception translation. By default when a class is annotated with #Repository Spring will register a PersistenceExceptionTranslationInterceptor which will translate exceptions to one of the Spring DataAccessExceptions. By default it translates all exceptions UNLESS the exception thrown is declared in the throws clause.
This exception translation happens before the TransactionInterceptor and that way there is never an IllegalArgumentException thrown because that already got translated into something else.
Create your won custom exception (Extending from exception ) and apply noRollBackFor you custom exception class
I have a spring context file with several beans of type defined.
If the input to my program is "help" then I would like to display the bean names from the context file, so that the user can pick a particular bean and give it as input. The program would instantiate the bean with that name and perform some logic.
I am not able to query the list of bean names from a particular context file.
I don't want to use a properties file to store the bean names as I am already using spring context files. Is there a better way to do this ?
Spring's BeanFactory has got a method called String[] getBeanDefinitionNames(). See Javadoc here. You can iterate through the returned list and show them to the user. then you can do a getBean call on the chosen bean name to run the logic.
I have two models: User and Base.
User model:
http://pastebin.com/WdLzBkHJ
Base model:
http://pastebin.com/tQrEUaSu
At first I want to put your mind on this notation in Base model:
#org.hibernate.annotations.Entity(dynamicInsert=true,dynamicUpdate=true)
It doesn't work (in SQL Debug shown that Hibernate generated queries with using unnecessary columns which in MySQL are configured as nullable). Tell me please why? What am I doing wrong?
And the main problem is there (method in which user uploads base and string in this base inserts in the MySQL table after parsing):
http://pastebin.com/yG3Mapze
Insertation is VERY SLOW. I have file with 70000 string per line and I can't wait until Hibernate insert this string into DB. Maximum I was waiting for 30 minutes and that wasn't the end.
If I'll use raw queries like that:
DB.execute("INSERT INTO bases (user_id,email,password) VALUES (1,'" + email.replaceAll("'", "\'") + "','" + password.replaceAll("'", "\'") + "')");
instead of
b.save();
After that insertation of 70000 strings to DB completes after ~10-20 seconds.
So I can't understand where is the problem and how to fix it?
Also you can see this code above method declaration:
#NoTransaction
If I uncomment it then I'll recieve this exception:
#689mbad1k
Internal Server Error (500) for request POST /checker/uploadnewbase
JPA error
A JPA error occurred (The JPA context is not initialized. JPA Entity Manager automatically start when one or more classes annotated with the #javax.persistence.Entity annotation are found in the application.):
play.exceptions.JPAException: The JPA context is not initialized. JPA Entity Manager automatically start when one or more classes annotated with the #javax.persistence.Entity annotation are found in the application.
at play.db.jpa.JPA.get(JPA.java:22)
at play.db.jpa.JPA.em(JPA.java:51)
at play.db.jpa.JPQL.em(JPQL.java:16)
at play.db.jpa.JPQL.find(JPQL.java:44)
at models.User.find(User.java)
at controllers.Security.getUser(Security.java:30)
at controllers.GlobalController.userStat(GlobalController.java:21)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:476)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:471)
at play.mvc.ActionInvoker.handleBefores(ActionInvoker.java:320)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:140)
at Invocation.HTTP Request(Play!)
But in Play manual we can see that:
"If you want to prevent Play from starting any transaction at all, you can annotate the method with #play.db.jpa.NoTransaction.
To prevent transactions for all methods, you can annotate the Controller-class with #play.db.jpa.NoTransaction."
So I have three problems which I described:
About exception in NoTransaction.
About using dynamicInsert = true.
About improving perfomance for Hibernate like if I'll use raw queries.
The problem is the hibernate session, which must be cleared. Otherwise you get problems with memory and performance. You can found some information in http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html. Unfortunately I don't know how to get the HibernateSession. Perhaps you can get the EntityManager and work with it. But my experiences with Hibernate and Batch are really frustrating, so I would recommend to use your raw-solution.
I am using Spring with Velocity. At times velocity produces an exception like
Error in interpolating string literal : org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getMessage' in class org.springframework.web.servlet.support.RequestContext threw exception class org.springframework.context.NoSuchMessageException : No message found under code 'XX' for locale 'en_US'.
Question is - can I instruct spring to suppress NoSuchMessageException ? I am pretty new to Spring so do not know if I can create a exception handler which will not throw a exception if the message is not found? In my use case, it is a valid use case of not finding some of the messages in the messages.properties file.
[EDIT] - I found a way org.apache.velocity.app.event.MethodExceptionEventHandler to supply an even handler to velocity. I am however not sure how to register it with Spring.
It would be better, I think, to address the problem directly, rather than trying to suppress the exception, which could lead to avoid behaviour and uncompleted operations.
However, you didn't tell us how you'd want the system to respond in cases where the message is not defined for a given code. Do you want a blank String, or should the code itself be used as the default message?
I'm assuming that somewhere in your Spring context you have a defined a messageSource bean of some sort. These MessageSource beans usually have a property useCodeAsDefaultMessage. This defaults to false, but when set to true they will return the code itself as the message, in cases where no message is defined.
Alternatively, you can subclass the MessageSource class (whichever one you're using), and override the getDefaultMessage() method to handle cases where the code cannot be resolved.