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
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 working with Spring Boot, in which I am relatively new, and in this case I am doing a database validation through a Stored Procedue, which I could already solve, the reality is that until now I had done the tests sent the parameter of entry (a mobile number) by GET, but it is required for project reasons, send the parameter through POST, that is to say in a Body with the method:
Method Get
With a Body using the POST Method:
Request
{
"movil":"04242374781";
}
Reponse:
{
"result": "Cliente no encontrado",
"code": "NA22003"
}
mobile is an attribute of the database where the Stored Procedure is executed, for this case it is only necessary to pass that parameter to execute the SP, which returns a response that is not the same object of the database in which it is mobile, then you will see it in the code.
I understand that you can send the parameter for consultation with POST, but in my case try to guide me according to what I got on the internet, but I got an error:
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported]
My Code
Main class
package com.app.validacion;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
My controller
package com.app.validacion.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.app.validacion.dao.DriverBonificadosRepository;
import com.app.validacion.entity.RespuestaVo;
#RestController
public class DriverBonificadosController {
#Autowired // Inyeccion de Dependecia, en este caso del Respository
private DriverBonificadosRepository dao;
#GetMapping("/service/{movil}")
public RespuestaVo ConsultarMovil(#PathVariable("movil") String movil) {
System.out.println(movil);
return dao.validarClienteBonifiado(movil);
}
/*
the code I was trying to use to send a request in JSON and try to get the mobile parameter,but
I got an error:
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type
'text/plain' not supported]
/*
* #PostMapping(value = "/service",consumes = "application/json", produces="application/json")
* public RespuestaVo ValidateClient(#RequestBody DriverBonificados driver) {
* System.out.println(driver.getMovil());
* return dao.validarClienteBonifiado(driver.getMovil());
} */
}
My Repository
package com.app.validacion.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.app.validacion.entity.DriverBonificados;
import com.app.validacion.entity.RespuestaVo;
#Repository
public interface DriverBonificadosRepository extends JpaRepository<DriverBonificados, Integer> {
#Query(nativeQuery = true,value = "call ValidacionClienteBonificado(:movil)")
RespuestaVo validarClienteBonifiado(#Param("movil") String pMovil);
}
My Entity
package com.app.validacion.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="DriveBonificados")
public class DriverBonificados {
#Id
private int id;
private String movil;
private String contador;
private Date fecha_driver;
private Date fecha_alta;
private Date fecha_fin;
private Date codigo_transaccion;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMovil() {
return movil;
}
public void setMovil(String movil) {
this.movil = movil;
}
public String getContador() {
return contador;
}
public void setContador(String contador) {
this.contador = contador;
}
public Date getFecha_driver() {
return fecha_driver;
}
public void setFecha_driver(Date fecha_driver) {
this.fecha_driver = fecha_driver;
}
public Date getFecha_alta() {
return fecha_alta;
}
public void setFecha_alta(Date fecha_alta) {
this.fecha_alta = fecha_alta;
}
public Date getFecha_fin() {
return fecha_fin;
}
public void setFecha_fin(Date fecha_fin) {
this.fecha_fin = fecha_fin;
}
public Date getCodigo_transaccion() {
return codigo_transaccion;
}
public void setCodigo_transaccion(Date codigo_transaccion) {
this.codigo_transaccion = codigo_transaccion;
}
}
My Model Response
package com.app.validacion.entity;
public interface RespuestaVo {
String getCode();
String getResult();
}
Nice post, but the (first encountered problem) solution is trivial:
With:
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported]
and with this postman request, You need to:
postman specific: switch the (request>body) content type from "Text" to "JSON (application/json)"
generally: add a (http) header to Your request like
Content-Type: application/json;...
I want to use binary UUID in a MariaDB database used for a spring-boot project, instead of using varchar uuid. For now, I am able to create, save and search a binary UUID, by override the column length to 16 but I have to manually put the annotation #Column(length=16) on any UUID field.
Is there a way to globally made this modification in the project ?
In other words, is there a way that, for all UUID field in the project, jpa/hibernate create a column "binary(16)" instead of "binary(255)" ?
My problem is that, by default, an UUID is converted into a binary(255) into MariaDB, and with this configuration, JPA Repositories queries are not able to find any data when searching on a UUID field.
To achieve Jpa repositories queries, I have to add the #Column(length=16) on any UUID field.
I have tried to use a "#Converter" but the Convert annotation should not be used to specify conversion of the following: Id attributes, version attributes, relationship attributes etc... And it doesn't work with an uuid relationship field.
I have also tried to use my own custom hibernate type (example here : https://www.maxenglander.com/2017/09/01/optimized-uuid-with-hibernate.html) but the jpa repositories queries don't find anything.
Now i have this :
My abstract entity :
public abstract class GenericEntity {
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
#Column(length = 16)
private UUID id;
//...
}
When using an uuid in another object :
public abstract class AnotherEntity extends GenericEntity {
#NotNull
#Column(length = 16)
private UUID owner;
//...
}
I'm looking for a way to override the UUID field generation without putting the "#Column(length = 16)" everywhere.
It would be really great to avoid errors and / or omissions when using the UUID type in others features.
Thanks a lot !
The type descriptor, remapping the binary implementation onto OTHER Hibernate typedef:
import java.sql.Types;
import java.util.UUID;
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.sql.BinaryTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
public class MariaDBUuidTypeDescriptor extends BinaryTypeDescriptor {
private static final long serialVersionUID = 1L;
public static final MariaDBUuidTypeDescriptor INSTANCE = new MariaDBUuidTypeDescriptor();
public MariaDBUuidTypeDescriptor() {
super();
}
#Override
public int getSqlType() {
return Types.OTHER;
}
#Override
#SuppressWarnings("unchecked")
public BasicJavaDescriptor<UUID> getJdbcRecommendedJavaTypeMapping(TypeConfiguration typeConfiguration) {
return (BasicJavaDescriptor<UUID>) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( UUID.class );
}
}
The type itself, wrapping the descriptor above and binding it to the UUID classdef.
import java.util.UUID;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
public class MariaDBUuidType extends AbstractSingleColumnStandardBasicType<UUID> {
private static final long serialVersionUID = 1L;
public static final MariaDBUuidType INSTANCE = new MariaDBUuidType();
public MariaDBUuidType() {
super( MariaDBUuidTypeDescriptor.INSTANCE, UUIDTypeDescriptor.INSTANCE );
}
#Override
public String getName() {
return "mariadb-uuid-binary";
}
#Override
protected boolean registerUnderJavaType() {
return true;
}
}
The modified Hibernate dialect, making use of the type and remapping all its occurrences onto binary(16)
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.MariaDB103Dialect;
import org.hibernate.service.ServiceRegistry;
public class MariaDB103UuidAwareDialect extends MariaDB103Dialect {
#Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes( typeContributions, serviceRegistry );
registerColumnType( Types.OTHER, "uuid" );
typeContributions.contributeType( MariaDBUuidType.INSTANCE );
}
#Override
public String getTypeName(int code, long length, int precision, int scale) throws HibernateException {
String typeName = super.getTypeName(code, length, precision, scale);
if (Types.OTHER == code && "uuid".equals(typeName)) {
return "binary(16)";
} else {
return typeName;
}
}
}
Please note that this is Hibernale-only implementation, i.e. does not matter if you use it along Spring (Boot) or not.
I have an entity named EmployeeDepartment as below
#IdClass(EmployeeDepartmentPK.class) //EmployeeDepartmentPK is a serializeable object
#Entity
EmployeeDepartment{
#Id
private String employeeID;
#Id
private String departmentCode;
---- Getters, Setters and other props/columns
}
and I have a Spring Data Repository defined as as below
#RepositoryRestResource(....)
public interface IEmployeeDepartmentRepository extends PagingAndSortingRepository<EmployeeDepartment, EmployeeDepartmentPK> {
}
Further, I have a converter registered to convert from String to EmployeeDepartmentPK.
Now, for an entity, qualified by ID employeeID="abc123" and departmentCode="JBG", I expect the ID to use when SDR interface is called is abc123_JBG.
For example http://localhost/EmployeeDepartment/abc123_JBG should fetch me the result and indeed it does.
But, when I try to save an entity using PUT, the ID property available in BasicPersistentEntity class of Spring Data Commons is having a value of
abc123_JBG for departmentCode. This is wrong. I'm not sure if this is an expected behaviour.
Please help.
Thanks!
Currently Spring Data REST only supports compound keys that are represented as by a single field. That effectively means only #EmbeddedId is supported. I've filed DATAJPA-770 to fix that.
If you can switch to #EmbeddedId you still need to teach Spring Data REST the way you'd like to represent your complex identifier in the URI and how to transform the path segment back into an instance of your id type. To achieve that, implement a BackendIdConverter and register it as Spring bean.
#Component
class CustomBackendIdConverter implements BackendIdConverter {
#Override
public Serializable fromRequestId(String id, Class<?> entityType) {
// Make sure you validate the input
String[] parts = id.split("_");
return new YourEmbeddedIdType(parts[0], parts[1]);
}
#Override
public String toRequestId(Serializable source, Class<?> entityType) {
YourIdType id = (YourIdType) source;
return String.format("%s_%s", …);
}
#Override
public boolean supports(Class<?> type) {
return YourDomainType.class.equals(type);
}
}
If you can't use #EmbeddedId, you can still use #IdClass. For that, you need the BackendIdConverter as Oliver Gierke answered, but you also need to add a Lookup for your domain type:
#Configuration
public class IdClassAllowingConfig extends RepositoryRestConfigurerAdapter {
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.withEntityLookup().forRepository(EmployeeDepartmentRepository.class, (EmployeeDepartment ed) -> {
EmployeeDepartmentPK pk = new EmployeeDepartmentPK();
pk.setDepartmentId(ed.getDepartmentId());
pk.setEmployeeId(ed.getEmployeeId());
return pk;
}, EmployeeDepartmentRepository::findOne);
}
}
Use #BasePathAwareController to customize Spring data rest controller.
#BasePathAwareController
public class CustInfoCustAcctController {
#Autowired
CustInfoCustAcctRepository cicaRepo;
#RequestMapping(value = "/custInfoCustAccts/{id}", method = RequestMethod.GET)
public #ResponseBody custInfoCustAccts getOne(#PathVariable("id") String id) {
String[] parts = id.split("_");
CustInfoCustAcctKey key = new CustInfoCustAcctKey(parts[0],parts[1]);
return cicaRepo.getOne(key);
}
}
It's work fine for me with sample uri /api/custInfoCustAccts/89232_70
A more generic approach would be following -
package com.pratham.persistence.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.istack.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.data.rest.webmvc.spi.BackendIdConverter;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import javax.persistence.EmbeddedId;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Base64;
import java.util.Optional;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Customization of how composite ids are exposed in URIs.
* The implementation will convert the Ids marked with {#link EmbeddedId} to base64 encoded json
* in order to expose them properly within URI.
*
* #author im-pratham
*/
#Component
#RequiredArgsConstructor
public class EmbeddedBackendIdConverter implements BackendIdConverter {
private final ObjectMapper objectMapper;
#Override
public Serializable fromRequestId(String id, Class<?> entityType) {
return getFieldWithEmbeddedAnnotation(entityType)
.map(Field::getType)
.map(ret -> {
try {
String decodedId = new String(Base64.getUrlDecoder().decode(id));
return (Serializable) objectMapper.readValue(decodedId, (Class) ret);
} catch (JsonProcessingException ignored) {
return null;
}
})
.orElse(id);
}
#Override
public String toRequestId(Serializable id, Class<?> entityType) {
try {
String json = objectMapper.writeValueAsString(id);
return Base64.getUrlEncoder().encodeToString(json.getBytes(UTF_8));
} catch (JsonProcessingException ignored) {
return id.toString();
}
}
#Override
public boolean supports(#NonNull Class<?> entity) {
return isEmbeddedIdAnnotationPresent(entity);
}
private boolean isEmbeddedIdAnnotationPresent(Class<?> entity) {
return getFieldWithEmbeddedAnnotation(entity)
.isPresent();
}
#NotNull
private static Optional<Field> getFieldWithEmbeddedAnnotation(Class<?> entity) {
return Arrays.stream(entity.getDeclaredFields())
.filter(method -> method.isAnnotationPresent(EmbeddedId.class))
.findFirst();
}
}
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"")