I'm trying to clear Hibernate cache, but I can't get the Ehcache context to clear it.
Thanks in advance.
CacheConfiguration.java,
public class CacheConfiguration {
private final javax.cache.configuration.Configuration<Object, Object> jcacheConfiguration;
public CacheConfiguration(JHipsterProperties jHipsterProperties) {
JHipsterProperties.Cache.Ehcache ehcache = jHipsterProperties.getCache().getEhcache();
jcacheConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration(
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class,
ResourcePoolsBuilder.heap(ehcache.getMaxEntries()))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ehcache.getTimeToLiveSeconds())))
.build());
}
#Bean
public JCacheManagerCustomizer cacheManagerCustomizer() {
return cm -> {
createCache(cm, co.interedes.repository.UserRepository.USERS_BY_LOGIN_CACHE);
createCache(cm, co.interedes.repository.UserRepository.USERS_BY_EMAIL_CACHE);
cm.createCache(co.interedes.domain.EntityAuditEvent.class.getName(), jcacheConfiguration);
// jhipster-needle-ehcache-add-entry
};
}
private void createCache(javax.cache.CacheManager cm, String cacheName) {
javax.cache.Cache<Object, Object> cache = cm.getCache(cacheName);
if (cache != null) {
cm.destroyCache(cacheName);
}
cm.createCache(cacheName, jcacheConfiguration);
}
}
In this post https://www.journaldev.com/2969/hibernate-caching-first-level-cache clear the first level, but in Jhipster the config its different
Related
I have done some tests on these two classes. Could someone please help to determine if these two classes are threadsafe? Could someone help to identify if not using concurrentHashMap, but use HashMap would it cause any concurrent issue. How can I make it more threadsafe? What is the best approach to testing it with concurrent testing?
I tested it with Hashmap only and it works fine. However, my scale of test is around 20 req/s for 2 mins.
Can anyone suggest if I should increase the req rate and try again or can point somewhere that must require fix.
#Component
public class TestLonggersImpl
implements TestSLongger {
#Autowired
YamlReader yamlReader;
#Autowired
TestSCatalog gSCatalog;
#Autowired
ApplicationContext applicationContext;
private static HashMap<String, TestLonggerImpl> gImplHashMap = new HashMap<>();
private static final Longger LONGER = LonggerFactory.getLongger(AbstractSLongger.class);
#PostConstruct
public void init() {
final String[] sts = yamlReader.getTestStreamNames();
for (String st : sts) {
System.out.println(st);
LONGER.info(st);
}
HashMap<String, BSCatalog> statsCatalogHashMap = gSCatalog.getCatalogHashMap();
for (Map.Entry<String, BSCatalog> entry : statsCatalogHashMap.entrySet()) {
BSCatalog bCatalog = statsCatalogHashMap.get(entry.getKey());
//Issue on creating the basicCategory
SProperties sProperties = yamlReader.getTestMap().get(entry.getKey());
Category category = new BasicCategory(sProperties.getSDefinitions(),
bCatalog.getVersion(),
bCatalog.getDescription(), new HashSet<>());
final int version = statsCatalogHashMap.get(entry.getKey()).getVersion();
getTestImplHashMap().put(entry.getKey(),
applicationContext.getBean(TestLonggerImpl.class, category,
entry.getKey(),
version));
}
}
#Override
public void logMessage(String st, String message) {
if (getTestImplHashMap() != null && getTestImplHashMap().get(st) != null) {
getTestImplHashMap().get(st).log(message);
}
}
#VisibleForTesting
static HashMap<String, TestLonggerImpl> getTestImplHashMap() {
return gImplHashMap;
}
}
*** 2nd class
#Component
public class GStatsCatalog {
#Autowired
YamlReader yamlReader;
private static HashMap<String, BStatsCatalog> stCatalogHashMap = new HashMap<>();
#PostConstruct
public void init() {
String[] streams = yamlReader.getGSNames();
for (String stream : streams) {
BStatsCatalog bCatalog = new BStatsCatalog();
SProperties streamProperties = yamlReader.getGMap().get(stream);
bCatalog.setSName(stream);
int version = VERSION;
try {
version = Integer.parseInt(streamProperties.getVersion());
} catch (Exception e) {
System.out.println(e.getMessage());
}
bCatalog.setVersion(version);
bCatalog.setDescription(streamProperties.getDescription());
stCatalogHashMap.put(stream, bCatalog);
}
}
public static HashMap<String, BStatsCatalog> getCatalogHashMap() {
return stCatalogHashMap;
}
public void setYamlReader(YamlReader yamlReader) {
this.yamlReader = yamlReader;
}
}
I think the methods under #postconstruct are threadsafe. It only runs once after the bean created in the whole lifecircle of the bean.
I have the following code to register Mapping (version 4.2)
public class ModelMapperProfile : Profile
{
protected override void Configure()
{
CreateMap<Case, CaseModel>();
CreateMap<CaseDetail, CaseDetailModel>();
}
}
public static class AutoMapperService
{
public static MapperConfiguration Initialize()
{
MapperConfiguration config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<ModelMapperProfile>();
});
return config;
}
}
And I register the dependency using unity as follows...
public static void RegisterTypes(IUnityContainer container)
{
container.LoadConfiguration();
var mapper = AutoMapperService.Initialize()
.CreateMapper();
container.RegisterInstance<IMapper>(mapper);
}
My here service constructor..
public TaxLiabilityCaseService(IMapper mapper,
IUnitOfWork unitofWork,
IRepository<Case> caseR,
IRepository<CaseDetail> caseDetailR)
{
_mapper = mapper;
_unitofWork = unitofWork;
_caseR = caseR;
_caseDetailR = caseDetailR;
}
And I get the following error message..
The current type, AutoMapper.IMapper, is an interface and cannot be
constructed. Are you missing a type mapping?
Answers found here did not work for me
What am I missing here
Try following these steps (MVC5):
Get Unity Nuget package:
Unity.Mvc5
Create this class:
public class MapperConfig
{
public static IMapper Mapper { get; set; }
public static void RegisterProfiles()
{
var config = new MapperConfiguration(cfg =>
{
// add profiles here
});
config.AssertConfigurationIsValid();
Mapper = config.CreateMapper();
}
}
In the UnityConfig file (created by the package), add this:
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterInstance<IMapper>(MapperConfig.Mapper);
}
In the Global.asax, add these:
protected void Application_Start()
{
MapperConfig.RegisterProfiles();
UnityConfig.RegisterComponents();
}
You should be good after this.
I used Spring 4.1.0 with Hibernate 4.3.6 and all is Ok.
After Spring migration to 4.2.8, the persistence does not work.
No exception, no trace the persist methode of entity manager is called but nothing in the database.
It's like if the transaction manager was not working.
this is my persistence configuration :
#Configuration
#EnableTransactionManagement
public class PersistenceConfiguration {
#Bean
public BasicDataSource driverManagerDataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/xxx");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setValidationQuery("SELECT 1");
dataSource.setDefaultAutoCommit(false);
dataSource.setInitialSize(10);
dataSource.setMaxActive(20);
dataSource.setMaxIdle(10);
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
final LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
localContainerEntityManagerFactoryBean.setDataSource(driverManagerDataSource());
localContainerEntityManagerFactoryBean.setPersistenceUnitName("xxxPersistenceUnitName");
localContainerEntityManagerFactoryBean.setPackagesToScan("org.xxx.model");
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter());
final HashMap<String, String> map = new HashMap<>();
map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
map.put("hibernate.hbm2ddl.auto", "update");
map.put("hibernate.show_sql", "false");
map.put("hibernate.format_sql", "false");
localContainerEntityManagerFactoryBean.setJpaPropertyMap(map);
localContainerEntityManagerFactoryBean.setJpaDialect(new org.springframework.orm.jpa.vendor.HibernateJpaDialect());
return localContainerEntityManagerFactoryBean;
}
#Bean
public JpaTransactionManager transactionManager() {
final JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(localContainerEntityManagerFactoryBean().getNativeEntityManagerFactory());
return jpaTransactionManager;
}
Dependence injection :
#Configuration
#Import({PersistenceConfiguration.class, UserConfiguration.class, SecurityConfiguration.class})
#ComponentScan(basePackages = "org.xxx")
#EnableWebMvc
public class XxxProjectConfiguration {
private static Logger LOG = Logger.getLogger(XxxProjectConfiguration.class);
#Autowired
private Environment env;
#PostConstruct
public void initApp() {
LOG.debug("Looking for Spring profiles...");
if (env.getActiveProfiles().length == 0) {
LOG.info("No Spring profile configured, running with default configuration.");
} else {
for (String profile : env.getActiveProfiles()) {
LOG.info("Detected Spring profile: {}" + profile);
}
}
}
#Autowired
private UserConfiguration userConfiguration;
// DAO
#Bean
public RelationshipDAO relationshipDAO() {
return new RelationshipDAOImpl();
}
#Bean
public RelationshipStatusDAO relationshipStatusDAO() {
return new RelationshipStatusDAOImpl();
}
#Bean
public MessageDAO messageDAO() {
return new MessageDAOImpl();
}
// Services
#Bean
public UserServiceImpl userService() {
return new UserServiceImpl(userConfiguration.userDAO(), relationshipDAO(), relationshipStatusDAO(), messageDAO());
}
}
And
#Configuration
#Import(PersistenceConfiguration.class)
public class UserConfiguration {
#Bean
public UserDAO userDAO() {
return new UserDAOImpl();
}
}
The service :
#Transactional(propagation=Propagation.SUPPORTS)
public class UserServiceImpl implements UserService, Serializable {
private static final long serialVersionUID = 1L;
private UserDAO userDAO;
private RelationshipDAO relationshipDAO;
private RelationshipStatusDAO relationshipStatusDAO;
private MessageDAO messageDAO;
public UserServiceImpl(final UserDAO userDAO, final RelationshipDAO relationshipDAO, final RelationshipStatusDAO relationshipStatusDAO, final MessageDAO messageDAO) {
this.userDAO = userDAO;
this.relationshipDAO = relationshipDAO;
this.relationshipStatusDAO = relationshipStatusDAO;
this.messageDAO = messageDAO;
}
#Override
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = UserServiceException.class)
public RelationshipStatus wantsRelationship(final long fromUserId, final long toUserId) throws UserServiceException {
try {
final Relationship relationship = new Relationship(new Date());
User fromUser = userDAO.get(fromUserId);
User toUser = new User(toUserId);
relationship.getUsers().add(fromUser);
fromUser.getRelationships().add(relationship);
relationship.getUsers().add(toUser);
toUser.getRelationships().add(relationship);
relationship.setWantsFromUserId(fromUserId);
final Message message = new Message(fromUserId, "Hi ! My name is " + fromUser.getFirstName() + ", I want to meet you");
relationship.getMessages().add(message);
relationship.setStatus(new RelationshipStatus(Status.WANTS));
relationshipDAO.persist(relationship);
return relationship.getStatus();
} catch (Exception e) {
throw new UserServiceException(e);
}
}
...
}
I do not understand anything...
The missing code is :
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
How can i configure Atomikos for HazelCast instance.As per the mastering-hazel cast we can only do it in java.How can i configure like i do for databases.If configuring is java is the way,then how i can make use of TransactionalTask to remove the boilerplate code starting and committing the transactions.i have tried like
public void insertIntoGridJTA( final List<String> list)
throws NotSupportedException, SystemException,
IllegalStateException, RollbackException {
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
HazelcastXAResource xaResource = hazelcast.getXAResource();
TransactionContext context = xaResource.getTransactionContext();
hazelcast.executeTransaction(new TransactionalTask<Object>() {
public Object execute(TransactionalTaskContext context)
throws TransactionException {
// TODO Auto-generated method stub
TransactionalMap<Integer, String> map = context.getMap("demo");
System.out.println("map"+map.getName());
for (int i = 0; i < list.size(); i++) {
map.put(i, list.get(i));
}
return null;
}
});
}
But the transaction is not starting if i am using TransactionalTask
Did you had a look at the Atomikos example in our examples repo? https://github.com/hazelcast/hazelcast-code-samples/blob/master/transactions/xa-transactions/src/main/java/XATransaction.java
In addition to #noctarius, I have done it like this in the past
#Autowired
private JdbcTemplate jdbcTemplate;
#Autowired
private HazelcastXAResource hzXAResource;
#Autowired
private UserTransactionManager userTransactionManager;
#Transactional
public void insert() throws SystemException, RollbackException {
final Transaction transaction = userTransactionManager.getTransaction();
transaction.enlistResource(hzXAResource);
final TransactionContext hzTransactionContext = hzXAResource.getTransactionContext();
final TransactionalMap<Long, String> hzCustomerMap = hzTransactionContext.getMap("hzCustomerMap");
// Use a Java 8 stream to print out each tuple of the list
CUSTOMERS_TEST_DATA.forEach(customer -> {
log.info("Inserting customer record for {}", customer);
hzCustomerMap.put(customer.getId(), customer.toString());
});
jdbcTemplate.batchUpdate(Sql.SQL_INSERT.getSql(), new BatchPreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setString(1, CUSTOMERS_TEST_DATA.get(i).getFirstName());
ps.setString(2, CUSTOMERS_TEST_DATA.get(i).getLastName());
}
#Override
public int getBatchSize() {
return CUSTOMERS_TEST_DATA.size();
}
});
// Uncomment this to test the failure of the transaction
// hzCustomerMap.values((Predicate) entry -> {
// throw new RuntimeException();
// });
transaction.delistResource(hzXAResource, XAResource.TMSUCCESS);
}
My unit of work class is mentioned below and I am using Ninject and I have tried injecting IUnitOfWork per request per thread scope, transient etc. but I am still getting error which is:
"Message":"An error has occurred.","ExceptionMessage":"The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.","ExceptionType":"System.InvalidOperationException
I get this error when i make two web API (get) calls at the same time using angularJS and it shows error at the point _context.Set<TEntity>().FirstOrDefault(match);
public class UnitOfWork : IUnitOfWork, IDisposable
{
private My_PromotoolEntities _uowDbContext = new My_PromotoolEntities();
private Dictionary<string, object> _repositories;
// Do it like this if no specific class file
private GenericRepository<MysPerson> _personRepository;
//private GenericRepository<MysDataSource> dataSourcesRepository;
//private GenericRepository<MysCountry> countryMasterRepository;
// Or like this if with specific class file.
private DataSourceRepository _dataSourcesRepository;
private CustomerRepository _customerRepository;
private DeviceRepository _deviceRepository;
private DeviceRegistrationRepository _deviceRegistrationRepository;
private EmailQueueRepository _emailQueueRepository;
public void SetContext(My_PromotoolEntities context)
{
_uowDbContext = context;
}
public void CacheThis(object cacheThis, string keyName, TimeSpan howLong)
{
Cacheing.StaticData.CacheStaticData(cacheThis, keyName, howLong);
}
public object GetFromCache(string keyName)
{
return Cacheing.StaticData.GetFromCache(keyName);
}
public GenericRepository<T> GenericRepository<T>() where T : BaseEntity
{
if (_repositories == null)
{
_repositories = new Dictionary<string, object>();
}
var type = typeof(T).Name;
if (!_repositories.ContainsKey(type))
{
var repositoryType = typeof(GenericRepository<>);
var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof(T)), _uowDbContext);
_repositories.Add(type, repositoryInstance);
}
return (GenericRepository<T>)_repositories[type];
}
public GenericRepository<MysPerson> PersonRepository
{
get
{
if (this._personRepository == null)
{
this._personRepository = new GenericRepository<MysPerson>(_uowDbContext);
}
return _personRepository;
}
}
public DataSourceRepository DataSourcesRepository
{
get
{
if (this._dataSourcesRepository == null)
{
this._dataSourcesRepository = new DataSourceRepository(_uowDbContext);
}
return _dataSourcesRepository;
}
}
public CustomerRepository CustomerRepository
{
get
{
if (this._customerRepository == null)
{
this._customerRepository = new CustomerRepository(_uowDbContext);
}
return _customerRepository;
}
}
public DeviceRepository DeviceRepository
{
get
{
if (this._deviceRepository == null)
{
this._deviceRepository = new DeviceRepository(_uowDbContext);
}
return _deviceRepository;
}
}
public DeviceRegistrationRepository DeviceRegistrationRepository
{
get
{
if (this._deviceRegistrationRepository == null)
{
this._deviceRegistrationRepository = new DeviceRegistrationRepository(_uowDbContext);
}
return _deviceRegistrationRepository;
}
}
public EmailQueueRepository emailQueueRepository
{
get
{
if (this._emailQueueRepository == null)
{
this._emailQueueRepository = new EmailQueueRepository(_uowDbContext);
}
return _emailQueueRepository;
}
}
/// <summary>
/// Commits all changes to the db. Throws exception if fails. Call should be in a try..catch.
/// </summary>
public void Save()
{
try
{
_uowDbContext.SaveChanges();
}
catch (DbEntityValidationException dbevex)
{
// Entity Framework specific errors:
StringBuilder sb = new StringBuilder();
var eve = GetValidationErrors();
if (eve.Count() > 0)
{
eve.ForEach(error => sb.AppendLine(error));
}
ClearContext();
// Throw a new exception with original as inner.
var ex = new Exception(sb.ToString(), dbevex);
ex.Source = "DbEntityValidationException";
throw ex;
}
catch (Exception)
{
ClearContext();
throw;
}
}
private void ClearContext()
{
DetachAll();
}
private void DetachAll()
{
foreach (DbEntityEntry dbEntityEntry in _uowDbContext.ChangeTracker.Entries())
{
if (dbEntityEntry.Entity != null)
{
dbEntityEntry.State = EntityState.Detached;
}
}
}
/// <summary>
/// Checks for EF DbEntityValidationException(s).
/// </summary>
/// <returns>Returns a List of string containing the EF DbEntityValidationException(s).</returns>
public List<string> GetValidationErrors()
{
if (_uowDbContext.GetValidationErrors().Count() != 0)
{
return _uowDbContext.GetValidationErrors().Select(e => string.Join(Environment.NewLine, e.ValidationErrors.Select(v => string.Format("{0} - {1}", v.PropertyName, v.ErrorMessage)))).ToList();
}
return null;
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_uowDbContext.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
You should never use a context in 2 places at the same time, that's exactly why you are getting this error. From the MSDN documentation:
Thread Safety: Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
It is a little hard to make suggestions without a repro but there is a brute force approach that should resolve the issue. If you have an interception point before/during DI setup then you can cause all the context initialization etc to happen by creating an instance of your context and calling ctx.Database.Initialize(force: false); Passing 'force: false' will ensure that the initialization still only happens once per AppDomain