I'm trying to use Spring Test DBUnit for running an integration test that checks if a DAO's services are running correctly. For two similar entities, I was able to create tests that run OK, but for this particular entity, the test can't run properly.
The test will be ignored, and the only Exception I will see in the console is:
java.lang.IllegalArgumentException: Unable to load dataset from "data/offline_message.xml" using class com.github.springtestdbunit.dataset.FlatXmlDataSetLoader
Here are the relevant files. XML file:
<dataset>
<mp_account id="1" auth_hash="ted.mosby" first_name="Ted" last_name="Mosby" credential="EMAIL" transport_session="someTransportSession"/>
<mp_account id="2" auth_hash="lily.aldrin" first_name="Lily" last_name="Aldrin" credential="MEH" transport_session="someTransportSession"/>
<mp_message id="1" recipient_account_id="1" sender_account_id="2"/>
</dataset>
Test class that is failing:
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.somecompany.messaging.domain.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Date;
import java.util.List;
#DatabaseSetup("data/message.xml")
public class MessageDaoTest extends AbstractDaoTest<Message> {
private static final Long ACCOUNT_ID = 1L;
public static final long DATE_LONG = 1431018764154L;
private static final Date LAST_UPDATE_TS = new Date(DATE_LONG);
#Autowired
MessageDao MessageDao;
#BeforeMethod
public void setUp() throws Exception {
this.setDao(MessageDao);
}
#Test
#Transactional
public void testFindMessages() throws Exception {
List<Message> Messages = this.MessageDao.findMessages(ACCOUNT_ID, LAST_UPDATE_TS);
Assert.assertNotNull(Messages);
Assert.assertEquals(Messages.size(), 1);
}
}
Abstract test class, that extends from TestNG's class:
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;
#TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class })
#ContextConfiguration(locations = { "classpath:test-context.xml" })
public class AbstractDaoTest <T> extends AbstractTestNGSpringContextTests {
private GenericDao<T> dao;
#Transactional
public T create(T t){
return dao.create(t);
}
#Transactional
public void delete(Object id){
dao.delete(id);
}
#Transactional
public T find(Object id){
return dao.find(id);
}
#Transactional
public T update(T t){
return dao.update(t);
}
public void setDao(GenericDao<T> dao) {
this.dao = dao;
}
}
Finally, the Entity:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import javax.persistence.*;
#NamedQueries({
#NamedQuery(
name = "findMessagesQuery",
query = "select om from Message om where om.recipientAccount.id=:accountId " +
"and om.lastUpdatedTs>:time and om.lastUpdatedTs+om.expirationPeriod>:now " +
"order by om.lastUpdatedTs asc"
),
#NamedQuery(
name = "findExpiredMessagesQuery",
query = "select om from Message om where om.lastUpdatedTs+om.expirationPeriod<:now"
)
})
#Entity
#Table(name="mp_message")
public class Message extends AbstractModel {
#JoinColumn(name="recipient_account_id", updatable = false)
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Account recipientAccount;
#JoinColumn(name="sender_account_id", updatable = false)
#ManyToOne(optional = false, fetch = FetchType.LAZY)
private Account senderAccount;
#Column(name="message_body", length=2048)
private String messageBody;
#Column(name="expiration_period")
private Long expirationPeriod;
// Getters, setters, etc excluded for brevity
}
Just a sidenote: I have "obscured" the Entity name (dammned lawyers!), so there could be some small name mistakes. Please bear with me on this ;)
If you need some additional details, please let me know.
Thanks in advance
try to add classpath: before your path, so:
#DatabaseSetup("classpath:data/message.xml")
Just do this, it works. the relative path can be used.
#DatabaseSetup("/data/message.xml"")
Related
This is my OSGI configuration file which is having three names. I want to read these values in a servlet and sort them Alphabetically and send that response to a ajax to display in a custom component AEM.
package com.demo.training.core.services.impl;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import com.demo.training.core.services.MyProjectServ;
#Component(service=MyProjectServ.class,immediate = true)
#Designate(ocd= MyProject.ServiceConfig.class)
public class MyProject implements MyProjectServ {
#ObjectClassDefinition(name="My-Project OSGI",
description="Demo OSGI configuration")
public #interface ServiceConfig {
#AttributeDefinition(
name="Name1",
description="Add First name",
type = AttributeType.STRING
)
public String Name1() default "Abhinay";
#AttributeDefinition(
name="Name2",
description="Add second name ",
type = AttributeType.STRING
)
public String Name2() default "Pavan";
#AttributeDefinition(
name="Name3",
description="Add third name ",
type = AttributeType.STRING )
public String Name3() default "Ram";
}
private String Name1;
private String Name2;
private String Name3;
#Activate
protected void activate(ServiceConfig myconfig) {
Name1=myconfig.Name1();
Name2=myconfig.Name2();
Name3=myconfig.Name3();
}
#Override
public String getNAME1() {
return Name1; }
#Override
public String getNAME2() {
return Name2; }
#Override
public String getNAME3() {
return Name3;
} }
'''This is my Servlet code , I have wrote multiple resp.getwriter() to see upto which line it is working. It is working upto response named a1(i.e below dictionary command). Could anyone please help to get values from osgi configuration to this servlet ?
package com.demo.training.core.servlets;
import java.io.IOException;
import java.util.Arrays;
import java.util.Dictionary;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
#Component(service=Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Practice Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.paths=/bin/myproject",
"sling.servlet.extensions=" + "txt"
})
public class MyProjectServlet extends SlingAllMethodsServlet {/**
*
*/
private static final long serialVersionUID = 1L;
#Reference
private ConfigurationAdmin MYPROJECT_CONFIG;
private static final String MY_PROJECT="com.demo.training.core.services.impl.MyProject";
#Override
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
Configuration My_Servlet=MYPROJECT_CONFIG.getConfiguration(MY_PROJECT);
Dictionary<String,Object> property =My_Servlet.getProperties();
resp.getWriter().write("a1");
String first=property.get("Name1").toString();
String second=property.get("Name2").toString();
String third=property.get("Name3").toString();
resp.getWriter().write("a2");
resp.getWriter().write(first);
resp.getWriter().write("a3");
String[] myArray = new String[]{first,second,third};
Arrays.sort(myArray);
String js=myArray.toString();
resp.getWriter().write(js);
}
}
You try to use the #reference annotation for your service. If this object null you can use the ResourceResolverFactoy. This object does always exists, else you have your instance has a serious problem:
Map<String, Object> serviceParameter = new HashMap<>();
serviceParameter.put(ResourceResolverFactory.SUBSERVICE, Put the name name of your service here);
return resolverFactory.getServiceResourceResolver(serviceParameter);
In Servlet use annotation #reference to inject the ResourceResolverFactoy:
#Reference
private ResourceResolverFactory ...;
By the way, have an eye to java code convetions. Method names starts always with smal letters even in service configs.
I am trying to insert data into the h2 database taking input from user.But primary key is getting inserted but the other is stored as null.
Here is my application.properties
spring.sql.init.platform==h2
spring.datasource.url=jdbc:h2:mem:preethi
spring.jpa.defer-datasource-initialization: true
spring.jpa.hibernate.ddl-auto=update
Here is Controller class AlienController.java
package com.preethi.springbootjpa.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.preethi.springbootjpa.model.Alien;
import com.preethi.springbootjpa.repo.AlienRepo;
#Controller
public class AlienController {
#Autowired
AlienRepo repo;
#RequestMapping("/")
public String home()
{
return "home.jsp";
}
#RequestMapping("/addAlien")
public String addAlien( Alien alien)
{
repo.save(alien);
return "home.jsp";
}
}
Here is Alien.java
package com.preethi.springbootjpa.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.springframework.stereotype.Component;
#Component
#Entity
public class Alien {
#Id
private int aid;
private String aname;
public Alien()
{
}
public Alien(int aid, String aname) {
super();
this.aid = aid;
this.aname = aname;
}
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getName() {
return aname;
}
public void setName(String name) {
this.aname = name;
}
#Override
public String toString() {
return "Alien [aid=" + aid + ", name=" + aname + "]";
}
}
Here is AlienRepo.java
package com.preethi.springbootjpa.repo;
import org.springframework.data.repository.CrudRepository;
import com.preethi.springbootjpa.model.Alien;
public interface AlienRepo extends CrudRepository<Alien,Integer>{
}
Here is data.sql;
insert into alien values(101,'Preethi');
when I try to insert data from data.sql,it is getting inserted but when I try to insert data taking input from user, data is stored as null(except primary key).
Here is the table :
table
I got the same issue when i forgot to add the gettters and setters for an entity class.
Finally solved it, there is no problem with the code...It's just all the configuraton things that messed up.
Just did everything from scratch and took care of build path and configurations.
Solved..
The sonar file in question gives false positives for duplicate blocks of code and I need to curb it at the file level. Is there any annotation or a configuration that can ignore the java class?
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.io.Serializable;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown=true)
public class SnbTransactionVo implements Serializable {
private static final long serialVersionUID = 7178997834378189890L;
private Integer cellComputerNo;
private String tradingDate;
public Integer getCellComputerNo() {
return cellComputerNo;
}
public void setCellComputerNo(Integer cellComputerNo) {
this.cellComputerNo = cellComputerNo;
}
public String getTradingDate() {
return tradingDate;
}
public void setTradingDate(String tradingDate) {
this.tradingDate = tradingDate;
}
}
You can use this annotation :
#java.lang.SuppressWarnings("squid:S00112")
Where squid:S00112 is the Sonar ID issue
I return an object instance of the following class from a Spring RestController method.
package x
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#XmlRootElement(name = "invoices")
public class Invoices implements Serializable {
private Info info;
private Set<Customer> customers = new HashSet<>();
private List<Invoice> invoices = new ArrayList<>();
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
#XmlElement(name = "customer")
public Set<Customer> getCustomers() {
return customers;
}
public void setCustomers(Set<Customer> customers) {
this.customers = customers;
}
#XmlElement(name = "invoice")
public List<Invoice> getInvoices() {
return invoices;
}
public void setInvoices(List<Invoice> invoices) {
this.invoices = invoices;
}
}
The Controller method has the signature;
#RequestMapping(value = "/invoice", method = RequestMethod.GET, produces = "application/xml; charset=UTF-8")
This returns an XML with an unexpected div element and an attribute named slick_uniqueid on the top element. How do I get rid of this, and where does this come from?
<invoices slick-uniqueid="3">
<div>
<a id="slick_uniqueid" />
</div>
I found the answer to this myself. The raw response from the server does not include this attribute, nor the extra element. It's chrome that modifies the XML slightly when it displays it in-browser. The attribute and element is not there if I do a 'view source' either. Strange. I have never noticed that before
public class App
{
public static void main( String[] args )
{
//test insert
tx = session.beginTransaction();
System.out.println("Maven + Hibernate + MySQL");
// Session session = HibernateUtil.getSessionFactory().openSession();
//session.beginTransaction();
Stock stock = new Stock();
stock.setStockCode("7000");
stock.setStockName("z");
session.saveOrUpdate(stock);
}
Stock.java
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import com.warp.intercept.*;
/**
* Stock generated by hbm2java
*/
#Entity
#Table(name = "stock", catalog = "mkyong", uniqueConstraints = {
#UniqueConstraint(columnNames = "STOCK_NAME"),
#UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable, IAuditLog {
private Integer stockId;
private String stockCode;
private String stockName;
public Stock() {
}
public Stock(String stockCode, String stockName) {
this.stockCode = stockCode;
this.stockName = stockName;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
return this.stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
#Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
public String getStockCode() {
return this.stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
#Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
public String getStockName() {
return this.stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
I have a java web application, I want to create audit logs in database for all the database changes like(column changed, value changed in column, userid, timestamp and some other fields). I want to create a generalized service which has methods exposed for such operations and I can access them from any other component in the application. As far as I have read, this can be done through hibernate envers or Spring AOP. Can you please suggest and provde me with an example which I can utilize to extend it further.
P.S. : I don't want to use trigger based logging for auditing database changes
Suppose this is my entiity stock; I am performing some simple save operations on the stock thru hibernate. Suppose, I have a main method and I perform below mentioned operation
Well, I am not a Spring or Hibernate user, so I do not know what exactly you need to capture. But if it is just the setters of any #Entity-annotated class, the whole thing would basically look like this:
Driver application:
package de.scrum_master.app;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Application {
public static void main(String[] args) {
System.out.println("Maven + Hibernate + MySQL");
// Session session = HibernateUtil.getSessionFactory().openSession();
// Transaction tx = session.beginTransaction();
Stock stock = new Stock();
stock.setStockCode("7000");
stock.setStockName("z");
// session.saveOrUpdate(stock);
}
}
Auditing aspect:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class DBAuditAspect {
#Before("execution(public void set*(*)) && #target(javax.persistence.Entity) && args(setterArgument)")
public void entitySetterExecution(Object setterArgument, JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint + " - " + setterArgument);
}
}
Console output:
Maven + Hibernate + MySQL
execution(void de.scrum_master.app.Stock.setStockCode(String)) - 7000
execution(void de.scrum_master.app.Stock.setStockName(String)) - z
The more general question of how to set up and use Spring AOP is explained in the documentation, chapter 9. Aspect Oriented Programming with Spring.