1.1.14.7.15. fejezet, Hibajelenségek
Java annotációk
@Autowired és @Repository
Hibajelenség:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [hu.kepeslap.back.dao.ImageDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Az @Autowired annotáció használatakor (mondjuk egy konstruktornál) ügyeljünk arra, hogy a paraméterül átadott interfészt megvalósító osztályt (pl.: valamelyik DAOImpl osztály) jelöljük meg a @Repository annotációval.
@SessionScoped vs. @Scope("session")
A kettőt ne keverjük, mert a távoli GET kérésekkor meglepődhetünk, hogy több szál is elkezd dolgozni a kérésen, és egyáltalán nincs szinkronizáció a szálak közt. Ez több adatbázis műveletet elronthat, hiába használunk tranzakció kezelést. ManagedBean esetén ajánlott a @SessionScoped használata, Spring használatakor pedig a @Scope("session"). @Repostitory annotációnál is ajánlott a Scope("session") használata. Figyeljük meg, hogy a @Component annotációs objektumokat nem hozza létre automatikusan egy XHTML fájlban elhelyezett hivatkozás, ezért ezeket @Autowired annotációval egy @Controll osztályba érdemes beemelni.
Perzisztencia kivétel detached objektum
org.hibernate.PersistentObjectException: detached entity passed to persist
Használd a merge funkciót.
Tomcat
Connection Timeout
A telepített Tomcat config/server.xml-ben állítható mind a szinkron, mind az aszinkron időkorlát:
<Connector port="8080" protocol="HTTP/1.1" minProcessors="3" maxProcessors="8" maxThreads="20" connectionTimeout="150000" asyncTimeout="90000" />
(150 másodperc és 90 másodperc)
Quartz Servlet inicializálása
"cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'"
A web.xml-ben a load-on-startup az init-param előtt volt. Helyesen:
<servlet> <servlet-name>QuartzInitializer</servlet-name> <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class> <init-param> <param-name>shutdown-on-unload</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>start-scheduler-on-load</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Quartz XMLSchedulingDataProcessorPlugin
Hibajelenség:
21:34:52,052 ERROR [org.quartz.core.ErrorLogger] (MyScheduler_QuartzSchedulerThread) An error occurred while scanning for the next triggers to fire.: org.quartz.JobPersistenceException: Couldn't acquire next trigger: Lock wait timeout exceeded; try restarting transaction [See nested exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction] at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2827) at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2755) at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3798) at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2751) at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:264) Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
Megoldás
org.quartz.plugin.jobInitializer.wrapInUserTransaction = true
quartz.properties
org.quartz.scheduler.instanceName = MyScheduler org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 5 org.quartz.threadPool.threadPriority = 5 org.quartz.jobStore.misfireThreshold = 60000 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.dataSource = myDS org.quartz.jobStore.nonManagedTXDataSource = myNonTxDS org.quartz.dataSource.myDS.jndiURL = java\:jboss/datasources/KepeslapR2DS org.quartz.dataSource.myNonTxDS.jndiURL = java\:jboss/datasources/KepeslapR2NonTxDS org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml org.quartz.plugin.jobInitializer.wrapInUserTransaction = true org.quartz.dataSource.myDS.maxConnections = 30
quartz-config.xml
<?xml version="1.0" encoding="UTF-8"?> <job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd" version="1.8"> <schedule> <job> <name>NOT-TIMED-JOB</name> <group>SERVER-SCAN-INTERVALL</group> <description>Send timeless mails</description> <job-class>hu.integrity.kepeslap.back.mail.DefaultMailDeliveryJob</job-class> <durability>true</durability> <recover>false</recover> </job> <trigger> <cron> <name>NOT-TIMED-TRIGGER</name> <group>SERVER-SCAN-INTERVALL</group> <job-name>NOT-TIMED-JOB</job-name> <job-group>SERVER-SCAN-INTERVALL</job-group> <!-- It will run every 5 seconds --> <cron-expression>0/20 * * * * ?</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>
homework-ds.xml
<?xml version="1.0" encoding="UTF-8"?> <datasources xmlns="http://www.jboss.org/ironjacamar/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.org/ironjacamar/schema http://docs.jboss.org/ironjacamar/schema/datasources_1_0.xsd"> <!-- The datasource is bound into JNDI at this location. We reference this in META-INF/persistence.xml --> <datasource jndi-name="java:jboss/datasources/KepeslapR2DS" pool-name="KepeslapR2" enabled="true" use-java-context="true"> <connection-url>jdbc:mysql://localhost:3306/kepeslap_jboss?useUnicode=true&autoReconnect=true&characterEncoding=UTF-8</connection-url> <driver>com.mysql</driver> <security> <user-name>admin</user-name> <password>pwd</password> </security> </datasource> <!-- Datasource for Quartz non CMT transactions --> <datasource jndi-name="java:jboss/datasources/KepeslapR2NonTxDS" pool-name="KepeslapR2NonTx" enabled="true" jta="false" use-java-context="true"> <connection-url>jdbc:mysql://localhost:3306/kepeslap_jboss?useUnicode=true&autoReconnect=true&characterEncoding=UTF-8</connection-url> <driver>com.mysql</driver> <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> <security> <user-name>admin</user-name> <password>pwd</password> </security> </datasource> </datasources>
persistance.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="primary"> <!-- If you are running in a production environment, add a managed data source, this example data source is just for development and testing! --> <!-- The datasource is deployed as WEB-INF/KepeslapR2-ds.xml, you can find it in the source at src/main/webapp/WEB-INF/KepeslapR2-ds.xml --> <jta-data-source>java:jboss/datasources/KepeslapR2DS</jta-data-source> <non-jta-data-source>java:jboss/datasources/KepeslapR2NonTxDS</non-jta-data-source> <properties> <!-- Properties for Hibernate --> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="false" /> </properties> </persistence-unit> </persistence>
- A hozzászóláshoz be kell jelentkezni