Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialShadd Anderson
Treehouse Project ReviewerHexadecimal string with odd number of characters
When I try to upload a gif, I get the following error code:
org.h2.jdbc.JdbcSQLException: Hexadecimal string with odd number of characters: "2016-08-06 23:39:06.423"; SQL statement:
insert into Gif (id, bytes, category_id, dateUploaded, description, favorite, hash, username) values (null, ?, ?, ?, ?, ?, ?, ?) -- (NULL, ?1, ?2, ?3, ?4, ?5, ?6, ?7) [90003-191]
Does anyone know how this could be fixed? I'll attach the relevant code (doesn't contain entirety of classes):
GifDAO Implementation:
@Repository
public class GifDAOImpl implements GifDao{
@Autowired
private SessionFactory sessionFactory;
@Override
public List<Gif> findAll() {
Session session = sessionFactory.openSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Gif> criteria = builder.createQuery(Gif.class);
criteria.from(Gif.class);
List<Gif> gifs = session.createQuery(criteria).getResultList();
session.close();
return gifs;
}
@Override
public Gif findById(Long id) {
Session session = sessionFactory.openSession();
Gif gif = session.get(Gif.class,id);
session.close();
return gif;
}
@Override
public void save(Gif gif) {
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(gif);
session.getTransaction().commit();
session.close();
}
GifService Implentation:
@Service
public class GifServiceImpl implements GifService {
@Autowired
private GifDao gifDao;
@Override
public List<Gif> findAll() {
return gifDao.findAll();
}
@Override
public Gif findById(Long id) {
return gifDao.findById(id);
}
@Override
public void save(Gif gif, MultipartFile file) {
try {
gif.setBytes(file.getBytes());
gifDao.save(gif);
} catch (IOException e) {
System.err.println("Unable to get byte array from uploaded file.");
}
}
GifController:
// Single GIF page
@RequestMapping("/gifs/{gifId}")
public String gifDetails(@PathVariable Long gifId, Model model) {
// TODO: Get gif whose id is gifId
Gif gif = gifService.findById(gifId);
model.addAttribute("gif", gif);
return "gif/details";
}
// GIF image data
@RequestMapping("/gifs/{gifId}.gif")
@ResponseBody
public byte[] gifImage(@PathVariable Long gifId) {
// TODO: Return image data as byte array of the GIF whose id is gifId
return gifService.findById(gifId).getBytes();
}
// Upload a new GIF
@RequestMapping(value = "/gifs", method = RequestMethod.POST)
public String addGif(@RequestParam MultipartFile file, Gif gif, RedirectAttributes attributes) {
// TODO: Upload new GIF if data is valid
gifService.save(gif, file);
attributes.addFlashAttribute("flash",new FlashMessage("GIF successfully uploaded", FlashMessage.Status.SUCCESS));
// TODO: Redirect browser to new GIF's detail view
return String.format("redirect:/gifs/%s",gif.getId());
}
Gif form:
<form th:object="${gif}" enctype="multipart/form-data" th:action="@{/gifs}" method="post">
<div class="row">
<div class="col s12 l8">
<div class="file-wrapper">
<input type="file" id="file" name="file"/>
<span class="placeholder" data-placeholder="Choose an image...">Choose an image...</span>
<label for="file" class="button">Browse</label>
</div>
</div>
</div>
<div class="row">
<div class="col s12 l8">
<input type="text" th:field="*{description}" placeholder="Description"/>
</div>
</div>
<div class="row">
<div class="col s12 l8">
<select th:field="*{category.id}" class="cs-select cs-skin-border">
<option value="" disabled="disabled">Select a category</option>
<option th:each="cat: ${categories}" th:value="${cat.id}" th:text="${cat.name}" th:style="|color:${cat.colorCode}|">Technology</option>
</select>
</div>
</div>
<div class="row">
<div class="col s12">
<button type="submit" class="button">Upload</button>
<a href="javascript:window.location = document.referrer;" class="button">Cancel</a>
</div>
</div>
</form>
Shadd Anderson
Treehouse Project ReviewerGitHub project: https://github.com/shadd-anderson/SpringWithHibernate
2 Answers
Shadd Anderson
Treehouse Project ReviewerFor future students that may run into this issue:
The problem was with how the h2 database was taking in the dateUploaded information. To verify you have the same problem, check the H2 Console and see if under the GIF table, the DATEUPLOADED is of the datatype VARBINARY. To fix it, simply run the following SQL query in the h2 Console:
DELETE FROM GIF;
ALTER TABLE GIF ALTER COLUMN DATEUPLOADED DATETIME;
THIS WILL DELETE ANYTHING YOU MIGHT ALREADY HAVE IN THE GIF TABLE
vikas Rai
9,703 PointsI was facing the same problem, thanks for help Shadd
Alexander Nikiforov
Java Web Development Techdegree Graduate 22,175 PointsAlexander Nikiforov
Java Web Development Techdegree Graduate 22,175 PointsHi, Shadd. Post your project on GitHub. Otherwise it is hard to say. Its important to look at all project files.
I tried once again with Chris code - it works for me. You see the problem is that when you are trying to insert
Gif
into database, he is trying to convertGif.dateUploaded
to "Hexadecimal", which is strange. When Chris is uploading his Gif, hisdateUploaded
is being saved in table asVARBINARY(255)
. There is something wrong with your code. The missing class that is not here isGif.java
Let me try to explain how it should work with saving
Gif.dateUploaded
. When you put object "gif" toThymeleaf
, usingformNewGif
method, you are creatingnew Gif()
object. Right at that point,dateUploaded
should be initialized, or may be later.Anyway, when you get to
addGif
method, before saving Gif, try to print Gif'sdateUploaded
to see how it looks like. That is the place where I would start searching the bug.But best would be to Share project on GitHub, so that I can reproduce error, and then write in Slack. It is easire to answer there.