I tried but could not find the right answer could you pleasehelp me out?
Table is creating but data is not getting inserted.I fixed the above error but data is not inserting in db for Hibernatetemplate save().
#Transactional(propagation=Propagation.REQUIRED,readOnly=false)
public class StudentDaoImplHT implements StudentDao {
private HibernateTemplate ht;
public void setHt(HibernateTemplate ht) {
this.ht = ht;
}
#Transactional
#Override
public int save(Student st) {
int i=(Integer) ht.save(st);;
System.out.println(st.getId());
System.out.println(st.getAddress());
System.out.println(st.getEmail());
System.out.println(st.getName());
return i; }
#Override
public boolean update(Student st) {
ht.saveOrUpdate(st);
return true;
}
#Override
public boolean delete(Student st) {
//ht.delete(st);
return true;
}
#Override
public Student findByPK(int id ) {
Student std=(Student) ht.get(Student.class, id);
return std;
}
#Override
public List<Student> findByAllUsingHQL() {
List<Student> list=(List<Student>) ht.find("from Student");
return list;
}
#Override
public List<Student> findByAllUsingCriteria() {
DetachedCriteria dc=DetachedCriteria.forClass(Student.class);
//dc.setProjection(projection);
//ht.findByCriteria(criteria)
List<Student> list= (List<Student>) ht.findByCriteria(dc);
return null;
}
}
Make sure you have the following property in your hibernate.cfg.xml:
"hibernate.connection.autocommit" true"
property name="hibernate.connection.autocommit" true property
Hope it helps.
Related
My scenario is need yo track entity property changes. I have used Hibernate PostUpdateEventListener interface to achieve that.
Following is my generic event listener class.
public abstract class EventListener<DOMAIN extends BaseModel> implements PostUpdateEventListener {
public abstract LogSupport getService();
public abstract BaseModel getLogDomain(DOMAIN domain);
#SuppressWarnings("unchecked")
private DOMAIN getDomain(BaseModel model) {
return (DOMAIN) model;
}
public void postUpdate(PostUpdateEvent event, BaseModel model) {
getService().createUpdateLog(getDomain(model), getPostUpdateEventNotes(event));
}
private String getPostUpdateEventNotes(PostUpdateEvent event) {
StringBuilder sb = new StringBuilder();
for (int p : event.getDirtyProperties()) {
sb.append("\t");
sb.append(event.getPersister().getEntityMetamodel().getProperties()[p].getName());
sb.append(" (Old value: ")
.append(event.getOldState()[p])
.append(", New value: ")
.append(event.getState()[p])
.append(")\n");
}
System.out.println(sb.toString());
return sb.toString();
}
}
And this is my custom entity listener.
#Component
public class AssetEventListener extends EventListener<Asset> {
private static final long serialVersionUID = -6076678526514705909L;
#Autowired
#Qualifier("assetLogService")
private LogSupport logSupport;
#Override
public LogSupport getService() {
AutowireHelper.autowire(this, logSupport);
return logSupport;
}
#PostPersist
public void onPostInsert(PostInsertEvent event) {
if (event.getEntity() instanceof BaseModel){
super.postPersist( event, (BaseModel) event.getEntity() );
}
}
#Override
public void onPostUpdate(PostUpdateEvent event) {
if (event.getEntity() instanceof BaseModel){
super.postUpdate( event, (BaseModel) event.getEntity() );
}
}
#Override
public BaseModel getLogDomain(Asset domain) {
return domain;
}
#Override
public boolean requiresPostCommitHanding(EntityPersister persister) {
return false;
}
}
And I called it from #EntityListeners
#Entity
#Table(name = "tbl_asset")
#EntityListeners({ AssetEventListener.class })
public class Asset extends BaseModel {
}
Listener not call when update the entity. Any help would be greatly appreciated.
Thanks,
public interface EAuditable {
public static interface Update{
public EUpdateInfo getUpdateInfo();
public void setUpdateInfo(EUpdateInfo updateInfo);
}
public static interface Create{
public ECreateInfo getCreateInfo();
public void setCreateInfo(ECreateInfo createInfo);
}
public static interface UpdateDate{
public ZonedDateTime getLastUpdatedOn();
public void setLastUpdatedOn(ZonedDateTime date);
}
public static interface UpdateUser{
public String getLastUpdatedBy();
public void setLastUpdatedBy(String user);
}
public static interface CreateDate{
public ZonedDateTime getCreatedOn();
public void setCreatedOn(ZonedDateTime date);
}
public static interface CreateUser{
public String getCreatedBy();
public void setCreatedBy(String user);
}
}
#Entity
#Table(name = "TRACKABLE_ITEM")
#Inheritance(strategy = InheritanceType.JOINED)
public class ETrackableItem extends AbstractIdTenantPersistable implements EAuditable.Create, EAuditable.Update {
#Embedded
private ECreateInfo createInfo;
#Embedded
private EUpdateInfo updateInfo;
}
#MappedSuperclass
//JPA: For Eclipse Link, use #AdditionaliCritera instead of #Filter and #FilterDef
#FilterDef(name="multiTenant", parameters=#ParamDef( name="tenant_id", type="string" ) )
#Filter(name="multiTenant", condition=":tenant_id = TENANT_ID")
public abstract class AbstractIdTenantPersistable extends AbstractIdPersistable {
#Column(name = "TENANT_ID", length = 12)
protected String tenantId;
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
protected AbstractIdTenantPersistable(){}
protected AbstractIdTenantPersistable(UUID id) {
super(id);
}
protected AbstractIdTenantPersistable(UUID id, String tenantId) {
super(id);
this.tenantId = tenantId;
}
}
#MappedSuperclass
#EntityListeners(value = { PersistableEntityListener.class })
#TypeDef(name = "json", typeClass = JsonUserType.class)
public abstract class AbstractPersistable {
public enum ConstraintType{UniqueName, Unique, Others};
/**
* Returns the constraint name to its type mapping.
* #param name
* #return
*/
public ConstraintType getConstraintType(String name){
return ConstraintType.Others;
}
}
public class PersistableEntityListener {
#PrePersist
public void prePersist(AbstractPersistable e) {
if (e instanceof EAuditable.Create){
EAuditable.Create create = (EAuditable.Create) e;
create.setCreateInfo(new ECreateInfo(ZonedDateTime.now(ZoneId.of("UTC")), getUserName()));
}
if (e instanceof EAuditable.CreateDate){
EAuditable.CreateDate createDate = (EAuditable.CreateDate) e;
createDate.setCreatedOn(ZonedDateTime.now(ZoneId.of("UTC")));
}
if (e instanceof EAuditable.CreateUser){
EAuditable.CreateUser createUser = (EAuditable.CreateUser) e;
createUser.setCreatedBy(getUserName());
}
if (e instanceof AbstractIdTenantPersistable){
((AbstractIdTenantPersistable)e).setTenantId(getTenantId());
}
preUpdate(e);
}
#PreUpdate
public void preUpdate(AbstractPersistable e) {
if (e instanceof EAuditable.Update){
EAuditable.Update update = (EAuditable.Update) e;
update.setUpdateInfo(new EUpdateInfo(ZonedDateTime.now(ZoneId.of("UTC")), getUserName()));
}
if (e instanceof EAuditable.UpdateDate){
EAuditable.UpdateDate updateDate = (EAuditable.UpdateDate) e;
updateDate.setLastUpdatedOn(ZonedDateTime.now(ZoneId.of("UTC")));
}
if (e instanceof EAuditable.UpdateUser){
EAuditable.UpdateUser updateUser = (EAuditable.UpdateUser) e;
updateUser.setLastUpdatedBy(getUserName());
}
}
private String getUserName() {
//checkContext();
if (isUserSet()){
return ContextHolder.get().getAuthenticatedContext().getUserName();
}
return "-";
}
private String getTenantId() {
//checkContext();
if (isTenantSet()){
return ContextHolder.get().getAuthenticatedContext().getTenantId();
}
return "-";
}
private boolean isUserSet(){
return ContextHolder.get() != null &&
ContextHolder.get().getAuthenticatedContext() != null &&
ContextHolder.get().getAuthenticatedContext().getUserName() != null;
}
private boolean isTenantSet(){
return ContextHolder.get() != null &&
ContextHolder.get().getAuthenticatedContext() != null &&
ContextHolder.get().getAuthenticatedContext().getTenantId() != null;
}
private boolean isContextSet(){
return isUserSet() && isTenantSet();
}
private void checkContext(){
BeanHolder.asserts().isTrue(
isContextSet(),`enter code here`
DomainException.class, "DOMAIN.CONTEXT_NOT_SET");
}
}
Below the code which was working fine for auto populate the audit info with the spring-data-jpa used with spring boot 1.4.x but it is not working when we upgraded to spring boot 2.1.x
Can any one please help if we have different way of handing for the same.
I need to follow this kind of #Embedded way of doing as here we are doing it by composition except inheritance.
Thanks in advance.
I am new to hibernate. I want to know if any crud operation happens so I decided to use jpa callback annotations. The problem is any of those #PrePersist #PostPersist #PreRemove #PostRemove not being called when I run the project and use UI components to perform delete & add operations. I use primefaces datatable so delete operation bounded to a ManagedBean -> MessageService ->MessageDAO. IF I only execute the main file to test it it works perfectly
MessageDAO:
#Component
public class MessageDAO {
#PersistenceContext
private EntityManager em;
#Transactional
public void register(Message message) {
em.persist(message);
}
#Transactional
public void delete(Integer id) {
Message m = em.find(Message.class, id);
em.remove(em.merge(m));
}
}
MessageListener
public class MessageListener {
#PrePersist
public void prePersist(Message o) {
System.out.println("Pre-Persistiting operation: " );
}
#PostPersist
public void postPersist(Message o) {
System.out.println("Post-Persist operation: " );
}
#PreRemove
public void preRemove(Message o) {
System.out.println("Pre-Removing operation: " );
}
#PostRemove
public void postRemove(Message o) {
System.out.println("Post-Remove operation: " );
}
#PreUpdate
public void preUpdate(Message o) {
System.out.println("Pre-Updating operation: ");
}
#PostUpdate
public void postUpdate(Message o) {
System.out.println("Post-Update operation: " );
}
}
Message
#EntityListeners(MessageListener.class)
#Entity
#Table(name = "messages")
public class Message implements Serializable {
private Integer messageId;
private String subject;
private String content;
public Message(){}
public Message(Integer messageId, String subject, String content) {
this.messageId = messageId;
this.subject = subject;
this.content = content;
}
#Id
#GeneratedValue
#Column(name = "MESSAGE_ID")
public Integer getMessageId() {
return messageId;
}
//getter setter
#PrePersist
public void prePersist() {
System.out.println("OLDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU!!!!!!!!!!!!");
}
}
As per the JPA spec, JPA callbacks/listeners are not called when using JPQL BULK DELETE. They are only called when using the JPA API (em.remove). Similarly the cache and managed entity objects do not reflect such a JPQL BULK DELETE call.
change Your code by following example hope it will work
#Transactional
public void delete(Long id) {
Message m = em.find(Message.class, id);
em.remove(em.merge(m));
}
}
I'm using Spring Boot with Mybatis, and I noticed that everytime I fetch some data with the same query, it will connect to db and query without using cache. So I search the solution for Mybatis with Redis, but cannot find one. All the answer is for Spring and xml configuration file, and I think it's better to use annotation. So, how to configure Redis as Cache to Mybatis in Spring Boot.
here is one of my solution, it just doesn't work.
MybatisRedisCache:
public class MybatisRedisCache implements Cache {
private static Logger logger = Logger.getLogger(MybatisRedisCache.class);
private Jedis redisClient = createClient();
/** The ReadWriteLock. */
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private String id;
public MybatisRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
logger.debug("MybatisRedisCache:id=" + id);
this.id = id;
}
#Override
public String getId() {
return this.id;
}
#Override
public int getSize() {
return Integer.valueOf(redisClient.dbSize().toString());
}
#Override
public void putObject(Object key, Object value) {
logger.debug("putObject:" + key + "=" + value);
redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));
}
#Override
public Object getObject(Object key) {
Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString())));
logger.debug("getObject:" + key + "=" + value);
return value;
}
#Override
public Object removeObject(Object key) {
return redisClient.expire(SerializeUtil.serialize(key.toString()), 0);
}
#Override
public void clear() {
redisClient.flushDB();
}
#Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
protected static Jedis createClient() {
try {
JedisPool pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1");
return pool.getResource();
} catch (Exception e) {
e.printStackTrace();
}
throw new RuntimeException("connect failed");
}
}
And here is LoggingRedisCache
public class LoggingRedisCache extends LoggingCache {
public LoggingRedisCache(String id) {
super(new MybatisRedisCache(id));
}
}
I am trying to mock a getBy() method after adding an element by a mocked service add.
This is what I have:
FeedItem feedItem = feedServiceTested.createFeedItem("Text Test", "Category Test", "Author Test");
Mockito.verify(feedRepository).add(feedItem);
Mockito.verify(feedRepository).findAllByCategory("Category Test");
However I get the following error:
Wanted but not invoked:
feedRepository.findAllByCategory(
"Category Test"
);
-> at ie.cit.adf.services.FeedServiceImplTest.testSearchFeedItemsByCategory(FeedServiceImplTest.java:55)
However, there were other interactions with this mock:
-> at ie.cit.adf.services.FeedServiceImpl.createFeedItem(FeedServiceImpl.java:44)
at ie.cit.adf.services.FeedServiceImplTest.testSearchFeedItemsByCategory(FeedServiceImplTest.java:55)
Any idea how to mock this findAllByCategory()?
Here are the 2 classes:
Repository:
#Secured("ROLE_USER")
public class JdbcFeedRepository implements FeedRepository {
private JdbcTemplate jdbcTemplate;
private FeedItemsMapper feedItemsMapper = new FeedItemsMapper();
public JdbcFeedRepository(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
public FeedItem findById(String feedItemId) {
return jdbcTemplate.queryForObject(
"SELECT ID, TEXT, CATEGORY, AUTHOR FROM FEEDITEMS WHERE ID=?",
feedItemsMapper,
feedItemId
);
}
#Override
public List<FeedItem> findAll() {
return jdbcTemplate.query(
"SELECT ID, TEXT, CATEGORY, AUTHOR FROM FEEDITEMS",
feedItemsMapper
);
}
#Override
public List<FeedItem> findAllByCategory(String category) {
return jdbcTemplate.query(
"SELECT ID, TEXT, CATEGORY, AUTHOR FROM FEEDITEMS WHERE CATEGORY=?",
feedItemsMapper,
category
);
}
#Override
public List<FeedItem> findAllByAuthor(String author) {
return jdbcTemplate.query(
"SELECT ID, TEXT, CATEGORY, AUTHOR FROM FEEDITEMS WHERE AUTHOR=?",
feedItemsMapper,
author
);
}
#Override
public void add(FeedItem feedItem) {
jdbcTemplate.update(
"INSERT INTO FEEDITEMS VALUES(?,?,?,?)",
feedItem.getId(),
feedItem.getText(),
feedItem.getCategory(),
feedItem.getAuthor()
);
}
#Override
public void delete(String feedItemId) {
jdbcTemplate.update("DELETE FROM FEEDITEMS WHERE ID=?", feedItemId);
}
/**
* Returns the name of the currently logged in Author.
*
* #return String
*/
private String getCurrentUser() {
return SecurityContextHolder.getContext().getAuthentication().getName();
}
}
class FeedItemsMapper implements RowMapper<FeedItem> {
#Override
public FeedItem mapRow(ResultSet rs, int rowNum) throws SQLException {
FeedItem feedItem = new FeedItem();
feedItem.setId(rs.getString("ID"));
feedItem.setText(rs.getString("TEXT"));
feedItem.setCategory(rs.getString("CATEGORY"));
feedItem.setAuthor(rs.getString("AUTHOR"));
return feedItem;
}
}
Service:
#Transactional
public class FeedServiceImpl implements FeedService {
private FeedRepository repo;
public FeedServiceImpl(FeedRepository repo) {
this.repo = repo;
}
#Override
public FeedItem get(String feedItemId) {
return repo.findById(feedItemId);
}
#Override
public List<FeedItem> getAllFeedItems() {
return repo.findAll();
}
#Override
public List<FeedItem> getAllFeedItemsByCategory(String category) {
return repo.findAllByCategory(category);
}
#Override
public List<FeedItem> getAuthorFeedItems(String author) {
return repo.findAllByAuthor(author);
}
#Override
public FeedItem createFeedItem(String text, String category, String author) {
FeedItem feedItem = new FeedItem();
feedItem.setText(text);
feedItem.setCategory(category);
feedItem.setAuthor(author);
repo.add(feedItem);
return feedItem;
}
#Override
public void delete(String feedItemId) {
repo.delete(feedItemId);
}
}
It seems your code never calls:
feedRepository.findAllByCategory("Category Test");
But you added a verifier for it. Mockito verify ensures the method is called one time in your test. When this did not happen its complains with an exception.
Your test calls:
feedServiceTested.createFeedItem(...)
Which only calls the following methods on repo:
add(feedItem)
Which is your first verify. So at the moment it seems your code did not use findAllByCategory and so does the verify throws this exception.
Or is there a call in FeedItem to the repo? Then please provide the code for this class too.