Why get java.sql.SQLException - spring-boot

I am developing a REST API Application for the first time and i was excited. Unfortunately, after the successful build, and when i run my application, i was facing error as below..
java.sql.SQLException: Invalid column index
at oracle.jdbc.driver.OraclePreparedStatement.setFormOfUseInternal(OraclePreparedStatement.java:10774) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
at oracle.jdbc.driver.OraclePreparedStatement.setFormOfUseInternal(OraclePreparedStatement.java:10755) ~[ojdbc8-21.1.0.0.jar:21.1.0.0.0]
Could you please help me fixing it. Thanks a lot in advance.
Here is the pieces of my code:
RestapiApplication.java
#SpringBootApplication
#ComponentScan(basePackages = "com.gfit.restapi")
#EnableSwagger2
public class RestapiApplication {
public static void main(String[] args) {
SpringApplication.run(RestapiApplication.class, args);
}
}
ModelEntity.java
/*#Data
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "TEST_EMP")*/
public class ModelEntity {
/*#Id*/
private BigInteger track_id;
private BigInteger seq_num;
private String request_type;
private String certification_id;
private String student_id;
// constructor, getter, setter and tostring
}
GfitRESTRepositoryImpl.java
#Repository
public class GfitRESTRepositoryImpl implements GfitRESTRepository{
#Autowired
private JdbcTemplate jdbcTemplate;
#Override
public ModelEntity findById(String certification_id) {
try {
ModelEntity cert_detail = jdbcTemplate.queryForObject("SELECT track_id, seq_num, request_type, certification_id, STUDENT_ID FROM tbl_ep_stg_caa_ext WHERE certification_id = '' ",
BeanPropertyRowMapper.newInstance(ModelEntity.class), certification_id);
System.out.println(cert_detail);
return cert_detail;
} catch (IncorrectResultSizeDataAccessException e) {
return null;
}
}
}
GfitRESTController.java
#CrossOrigin(origins = "http://localhost:3000")
#RestController
#RequestMapping("/api")
public class GfitRESTController {
#Autowired
GfitRESTRepository gfitRESTRepository;
//#GetMapping("/certification/detail/{certification_id}")
#RequestMapping(value = "/certification/detail/{certification_id}", method = RequestMethod.GET)
public ResponseEntity<ModelEntity> getCertificateByID(#PathVariable("certification_id") String certification_id) {
ModelEntity cert_detail = gfitRESTRepository.findById(certification_id);
if (cert_detail != null) {
return new ResponseEntity<>(cert_detail, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
My Actual DB query gives the below result, and which i was trying to execute in my code above :
Postman screenshot :
Screenshots From Swagger-UI Endpoint :

Can you try downgrading the OJDBC JAR to version 12.2.0.1? I'm facing a similar issue with an update statement in my own application. We had upgraded to 21.1 a little while back from 12.2 and we never faced this issue with the 12.2 driver. I spent hours trying to figure it out and ended up reverting the driver version just to test it out and the error went away.
https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8/12.2.0.1

Related

Jooq DataTypeException since Spring.Boot 2.4.x

I am getting a DataTypeException when retrieving data since the upgrade to Spring Boot 2.4.x. It worked fine with 2.3.9.RELEASE.
org.jooq.exception.DataTypeException: No Converter found for types MyBaseType and MyInheritType1 at
org.jooq.impl.Tools.converterOrFail(Tools.java:1132) at
org.jooq.impl.Tools.converterOrFail(Tools.java:1148) at
org.jooq.impl.AbstractRecord.get(AbstractRecord.java:270) at
org.jooq.impl.AbstractResultQuery.fetchOne(AbstractResultQuery.java:576) at
org.jooq.impl.SelectImpl.fetchOne(SelectImpl.java:3019)
MyInheritType1 extends MyBaseType.
The classes are using lombok #Data, so they should have the proper setters.
#Data
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "_class")
#JsonSubTypes(
{
#JsonSubTypes.Type(value = MyInheritType1.class, name = "Type1"),
#JsonSubTypes.Type(value = MyInheritType2.class, name = "Type2")
})
public class MyBaseType
{
private UUID id;
private String disclaimerLongText = "";
private LocalDateTime creationTime;
private Map<UUID, String> images = new HashMap<>();
}
The inherited type:
#Data
public class MyInheritType1 extends MyBaseType
{
private String baseMap;
private EnumType someEnum;
private List<LayerType> layerTypes = new ArrayList<>();
private double[] center;
}
I retrieve the data like this:
return dsl.select(PROJECT.DETAILS).from(PROJECT)
.where(PROJECT.ID.eq(id.toString()))
.fetchOne(PROJECT.DETAILS, MyInheritType1.class);
PROJECT.DETAILS is defined as this:
public final TableField<ProjectRecord, ProjectDetails> DETAILS = createField(DSL.name("details"), SQLDataType.JSONB.nullable(false), this, "", new ProjectDetailsBinding());
And ProjectDetailsBinding looks like this:
public class ProjectDetailsBinding extends JsonBBinding<MyBaseType>
{
#Override
protected Class<ProjectDetails> getBindingType()
{
return MyBaseType.class;
}
}
public abstract class JsonBBinding<T> implements Binding<JSONB, T>
{
private ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
protected abstract Class<T> getBindingType();
#Override
public Converter<JSONB, T> converter()
{
return new Converter<JSONB, T>()
{
#Override
public T from(JSONB o)
{
if (o == null)
return null;
try
{
return objectMapper.readValue(o.data(), getBindingType());
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
public JSONB to(T t)
{
try
{
return JSONB.valueOf(objectMapper.writeValueAsString(t));
} catch (JsonProcessingException e)
{
e.printStackTrace();
}
return null;
}
#Override
public Class<JSONB> fromType()
{
return JSONB.class;
}
#Override
public Class<T> toType()
{
return getBindingType();
}
};
}
[..]
}
Since it worked with 2.3.9.RELEASE, I am wondering what changed in Spring Boot or Jooq, that would cause this different behavior now?
Looks like https://github.com/jOOQ/jOOQ/issues/11762, fixed for 3.15.0 and 3.14.9, to be released soon. You can try building 3.14.9 from github or use a snapshot build from here: https://www.jooq.org/download/versions if you're licensed, to see if that fixes your issue.
Alternatively, you can try to use the fixed version of the DefaultConverterProvider and use that in your Configuration.
Since it worked with 2.3.9.RELEASE, I am wondering what changed in Spring Boot or Jooq, that would cause this different behavior now?
Typically, Spring Boot upgrades come with jOOQ upgrades. You could also downgrade your jOOQ dependency to what you were using before with Spring Boot 2.3.9

SpringBoot : getting error while uploading file

using spring-boot i m trying to post image but i got
org.thymeleaf.exceptions.TemplateInputException
entity class
#Entity
#Table(name="image")
public class ImageEntity {
#Id
#Column(name="imageId")
private String imageId;
#Column(name="imageName")
private String imageName;
#Column(name="type")
private String type;
/*#Column(name="size")
private long size;*/
#Column(name="imagepath")
private String path;
public ImageEntity(String imageName, String type, String path) {
super();
this.imageName = imageName;
this.type = type;
//this.size = size;
this.path = path;
}
Controller Class
#Controller
public class ImgContr {
public static final Logger logger =LoggerFactory.getLogger(ImgContr.class);
#Autowired
public ImgService imgService;
#PostMapping("/addImage")
public ImageEntity saveImage(#RequestBody ImageEntity imgent, RedirectAttributes redirectAttributes) throws Exception
{
return imgService.saveImage(imgent );
}
Domain Service
#Service
public class ImgService {
#Autowired
public ImageDao imageDao;
public ImageEntity saveImage(ImageEntity imgent) {
ImageEntity imgEngDom=new ImageEntity();
imgEngDom.setImageId(imgent.getImageId());
imgEngDom.setImageName( imgent.getImageName());
imgEngDom.setPath(imgent.getPath());
//imgEngDom.setSize(imgent.getSize());
imgEngDom.setType(imgent.getType());
return imageDao.saveImage(imgEngDom);
}
ImageDAO.java
#Repository
public class ImageDao {
#PersistenceContext
private EntityManager entityManager;
#Autowired
SessionFactory sessionFactory;
public ImageEntity saveImage(ImageEntity imgEngDom) {
Session session = null;
try {
session = sessionFactory.openSession();
session.beginTransaction();
session.save(imgEngDom);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
session.close();
}
return imgEngDom;
}
Payload Request.
{
"imageName": "Divya",
"type" : "jpg",
"path": " C:/Users/admin/Desktop"
}
//if i try to post image like this below in postman i got error
Error
{
"timestamp": 1548408353973,
"status": 500,
"error": "Internal Server Error",
"exception": "org.thymeleaf.exceptions.TemplateInputException",
"message": "Error resolving template \"addImage\", template might not
exist or might not be accessible by any of the configured Template
Resolvers",
"path": "/addImage"
}
I am new to springboot where i m wrong. Help me.
I think problem with your Controller configuration.
try this
#RestController
public class ImgContr {
instead of
#Controller
public class ImgContr {
For more in-depth details please follow >> Controller vs RestController
Note : Above solution works when you need a json response not a solution for Spring-mvc Projects.

Jmockit/Spring mocked dependency still calls the Real dependency

so I've been stuck on this problem all day.
I'm testing a class of type JdbcSupportDao in Spring 3.2. The problem is very self-explanatory if you just read the code, but I will briefly summarize:
I use the #Mocked annotation on a JdbcTemplate to mock querying the database. The problem is, after writing the Expectations block, the actual JdbcTemplate method is still being called, with JMockit apparently not entering in to the equation at all.
The following unit test fails:
/*#RunWith(SpringJUnit4ClassRunner.class)*/
#RunWith(JMockit.class)
#ContextConfiguration(locations={"classpath:studentAggregateReport-servlet.xml", "classpath:applicationContext-hibernate.xml"})
public class JdbcSSODaoTest extends AbstractTransactionalJUnit4SpringContextTests {
#Mocked
JdbcTemplate jdbcTemplate;
List<String> unameList;
SSODao ssoDao;
String DUMMY_ALCID = "yattayattayatta";
#Before
public void constructDao() {
this.ssoDao = new JdbcSSODao();
((JdbcSSODao) ssoDao).setJdbcTemplate(jdbcTemplate);
}
#Test
public void testGetUnameFromAlcId() {
unameList = new ArrayList<String>() {{
add("PEEPEE");
}};
//((JdbcSSODao) ssoDao).setJdbcTemplate(jdbcTemplate);
new Expectations() {{
jdbcTemplate.query(anyString, (ResultSetExtractor<String>)any); result = unameList;
}};
String uname = ssoDao.getUnameFromAlcId(DUMMY_ALCID);
assertNotNull(uname);
}
}
and here is the code for the class being tested:
public class JdbcSSODao extends JdbcDaoSupport implements SSODao {
#Override
public String getUnameFromAlcId(String alcid) {
String sql = SSOSqlUtil.createGetUnameByAlcIdSql(alcid);
logger.debug(sql);
List<String> resultLst = getJdbcTemplate().query(sql, new RowMapper<String>() {
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString(1);
}
});
if(resultLst.isEmpty()) return null;
return resultLst.get(0);
}
}
Please help :(
Sweet mother of God..
Apparently, you have to cast parameters of mocked methods to the exact type used in the call. This fixed it for me:
new Expectations() {{
jdbcTemplate.query(anyString, (RowMapper<String>)any); result = unameList;
}};

NullPointerException TopLevelTransaction.markAsRollbackOnly Neo4J-Boot for findAll() method

I am trying to follow Josh Long - Philip Sorst example in order to perform Angular SPA-Rest Authentication and CRUD actions using Neo4J as db (excellent work. Thanks a lot guys). But I am stuck at a very early stage and I suspect it's not my fault. Please help Neo4J-Angular-Spring lovers. My code can be found here and it is very easy to run just clone and give mvn spring-boot:run
Now the problem is that I get the following exception only for the findAll() method of the GraphRepository.
Caused by: java.lang.NullPointerException: null
at org.neo4j.kernel.TopLevelTransaction.markAsRollbackOnly(TopLevelTransaction.java:93)
... 88 common frames omitted
and I will replicate some of my code:
Neo4JConfig.java
#Configuration
#EnableNeo4jRepositories(basePackages = "demo.repository.neo4j")
public class Neo4JConfig extends Neo4jConfiguration {
public Neo4JConfig() {
setBasePackage("demo.model.neo4j");
}
#Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("data/demo.db");
}
#Bean
public Neo4jTemplate neo4jTemplate() {
return new Neo4jTemplate(graphDatabaseService());
}
}
NewsEntry.java
#NodeEntity
public class NewsEntry {
#GraphId
private Long id;
private String content;
public NewsEntry() {}
public NewsEntry(String b) {
this.content = b;
}
public Long getId() {
return this.id;
}
public String getContent() {
return this.content;
}
public void setId(Long id) {
this.id = id;
}
public void setContent(String content) {
this.content = content;
}
}
NewsEntryRepository.java
public interface NewsEntryRepository extends GraphRepository<NewsEntry> {
}
NewsEntryController.java
#RestController
class NewsController {
#Autowired
private NewsEntryRepository newsEntryRepository;
#RequestMapping("/news")
List<NewsEntry> entries() {
List<NewsEntry> list = new ArrayList<NewsEntry>();
Iterable<NewsEntry> results = newsEntryRepository.findAll();
for (NewsEntry r : results) {
list.add(r);
}
return list;
}
#RequestMapping(value = "/news/{id}", method = RequestMethod.DELETE)
void remove(#PathVariable Long id) {
this.newsEntryRepository.delete(id);
return;
}
#RequestMapping(value = "/news/{id}", method = RequestMethod.GET)
NewsEntry entry(#PathVariable Long id) {
return this.newsEntryRepository.findOne(id);
}
#RequestMapping(value = "/news/{id}", method = RequestMethod.POST)
NewsEntry update(#PathVariable Long id, #RequestBody NewsEntry news) {
NewsEntry old = this.newsEntryRepository.findOne(id);
old = news;
return this.newsEntryRepository.save(old);
}
#RequestMapping(value = "/news", method = RequestMethod.POST)
NewsEntry add(#RequestBody NewsEntry news) {
this.newsEntryRepository.save(new NewsEntry(news.getContent()));
return news;
}
}
OK Solution inspired from here https://github.com/mstahv/bootiful-neo4j-with-vaadin/blob/master/src/main/java/org/vaadin/neo4j/AppService.java. He is implementing a #Service annotated with #Transactional before using the repository in the controller.
You shouldn't have to override:
#Bean
public Neo4jTemplate neo4jTemplate() {
return new Neo4jTemplate(graphDatabaseService());
}
And can you try to add the annotation:
#EnableTransactionManagement
to your config?
Something is telling me that the solution is hiding somewhere here. I will give it a go and let you know.
OK This works only if you change the version of Spring-data-neo4j to 2.3.3.RELEASE. If you use the latest version you get the same problem as above. I think I should open an issue.
But that's not the solution as I would like to use Neo4J Server Community 2.0.3 to open the graph for visualization afterwards. Also I do not understand this solution beanfactories, injects instead of autowired???. However I will make another branch for this solution in my github repo.

Using session in old Petclinic example

I'm experimenting with the old Petclinic example and I noticed that the vets ArrayList in the SimpleJdbcClinic exists for the life of the session. It seems like it should exist only for the request since I don't see any annotations putting it into the session context. Could someone point out what I'm failing to understand?
Here is the vets class:
#XmlRootElement
public class Vets {
private List<Vet> vets;
#XmlElement
public List<Vet> getVetList() {
if (vets == null) {
vets = new ArrayList<Vet>();
}
return vets;
}
}
The service:
#Service
#ManagedResource("petclinic:type=Clinic")
public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean {
private SimpleJdbcTemplate simpleJdbcTemplate;
private SimpleJdbcInsert insertOwner;
private SimpleJdbcInsert insertPet;
private SimpleJdbcInsert insertVisit;
private final List<Vet> vets = new ArrayList<Vet>();
:
:
#Transactional(readOnly = true)
public Collection<Vet> getVets() throws DataAccessException {
synchronized (this.vets) {
if (this.vets.isEmpty()) {
refreshVetsCache();
}
return this.vets;
}
}
}
The controller mapping:
#RequestMapping("/vets")
public ModelMap vetsHandler() {
Vets vets = new Vets();
vets.getVetList().addAll(this.clinic.getVets());
return new ModelMap(vets);
}
Once the vets list is created it survives multiple requests.
Thanks
I think it avoids redundant database calls by storing all vets in the private final List<Vet> vets. Also vets variable is a property of a singleton #Service SimpleJdbcClinic

Resources