Spring get database table value on server startup - database

We are creating a spring and hibernate application and using a legacy database.
Our requirement is to get values from few database tables on server startup.
We are planning to put these values in properties files.So that we don't need to fetch DB for these values again and again.
We have used ApplicationListener to get hook on startup using following stackoverflow question:-
Listener for server starup and all spring bean loaded completely
the code being used is as below
#Component
public class SpringContextListener implements ApplicationListener<ContextRefreshedEvent> {
private List<Yosemitecompany> companyList = new ArrayList<Yosemitecompany>();
private YosemitecompanyRI iYosemitecompanyBO;
public SpringContextListener(){
}
public SpringContextListener(YosemitecompanyRI iYosemitecompanyBO) {
this.iYosemitecompanyBO = iYosemitecompanyBO;
}
public void onApplicationEvent(final ContextRefreshedEvent event) {
System.out.println("ApplicationListener Started"+iYosemitecompanyBO);
if(companyList == null || (companyList != null && companyList.size() <= 0) && iYosemitecompanyBO != null)
{
companyList = iYosemitecompanyBO.getCompanyDetailsWithStatus();
}
}
public List<Yosemitecompany> getCompanyList()
{
return companyList;
}
}
and this is the repository class
#Repository
#Transactional
public class YosemitecompanyRI implements IYosemitecompanyR{
static final Logger log = Logger.getLogger("YosemitecompanyDAOI");
#Autowired
private SessionFactory sessionFactory;
protected Session getSession() {
log.info(sessionFactory);
if (sessionFactory != null)
return sessionFactory.getCurrentSession();
else
return null;
}
#Override
public List<Yosemitecompany> getCompanyDetailsWithStatus()
{
List<Yosemitecompany> results = new ArrayList<Yosemitecompany>();
log.info("reached "+getSession());
if(getSession() != null)
{
log.info("executing query");
Criteria cr = getSession().createCriteria(Yosemitecompany.class);
cr.add(Restrictions.eq("cmpstatus",new BigDecimal(1)));
results = (List<Yosemitecompany>)cr.list();
}
return results;
}
}
Now on server startup..i get sessionFactory always as null..so my code for getting the list never gets executed.
i am new to spring and Hibernate.If this approach is fine then please help me to know what i am doing wrong.if there is a better approach to achieve please suggest that too.
Thanks in advance.

Related

Entity state is DETACHED when it should be Modified

I am trying to modify data and save changes to my database using EFCore 3.1.
but my modifications are not being saved to the database, so after further investigation I found out that after I pull my entity from the context, its state is DETACHED instead of ATTACHED,
so that's why the changes aren't being saved, because they're not tracked in the first place.
I couldn't figure out why this is happening, I made sure that I did not add AsNoTracking() when getting the entity.
Here are my classes and methods:
public class UserSettingsDataAccess : IUserSettingsDataAccess
private readonly NotificationDBContext _context;
private readonly IReminderDatesDataAccess _reminderDatesDataAccess;
public UserSettingsDataAccess(NotificationDBContext context, IReminderDatesDataAccess reminderDatesDataAccess)
{
_context = context;
_reminderDatesDataAccess = reminderDatesDataAccess;
}
public bool ToggleRemindersForAppointmentAsync(int appointment_id)
{
Appointments appointment = _appointmentDataAccess.GetByIdWithReminders(appointment_id);
if (appointment == null || appointment.Reminders == null)
return bool.Parse(null);
var x = _context.Entry(appointment).State;
appointment.Reminders.IsActive = !appointment.Reminders.IsActive;
var y = _context.Entry(appointment).State;
_context.SaveChanges();
var z = _context.Entry(appointment).State;
return appointment.Reminders.IsActive.Value;
}
//rest of code is omitted for brevity
}
This one uses another method to get the appointment, toggle its reminder , save changes and return the new reminder state. all of x,y,z variables have DETACHED value . when debugging
Here's the second class that contains the method that brings the appointment :
public class AppointmentDataAccess: IAppointmentDataAccess
{
private readonly NotificationDBContext _context;
public ReminderDatesDataAccess(NotificationDBContext context)
{
_context = context;
}
public Appointments GetByIdWithReminders(int appointment_id)
{
return _context.Appointments.Where(a => a.Id == appointment_id && a.DeletedAt == null)
.Include(a=>a.Reminders).FirstOrDefault();
}
}
Startup.cs :
services.AddDbContext<NotificationDBContext>(options => options
.UseSqlServer(Configuration.GetConnectionString("Database"))
, ServiceLifetime.Transient,ServiceLifetime.Transient);
and IUserSettingsDataAccess, IAppointmentDataAccess are just interfaces.
Can anyone point out why this is happening? and how to fix it? it's been driving me crazy for a good couple of hours . TIA!

where doese breeze fits into ntier architecture

i am Trying to fit in breezeJS with my existing architecture. I have a structure like
html/JS/Angular :: based view using hot-towel angular.
web api controllers :: whom the view calls.
Services layer :: that is being called from Web api. Any business logic goes here.
Unit of Work :: And (if) business logic requires to talk to data base for CRUDs it calls UOW.
Repository Pattern :: UOW is actually wrapping repositories. and repositores in turn talking to DbContexts.
Uptill now i was able to conver normal repositories implementation into the one using
public EFContextProvider<MyContext> DbContext { get; set; }
instead of just DbContext and i am also exposing MetaData using a string property with in UOW and IQueryables are returned using DbContext.Context.SomeEntity
Question 1 : Am i on right track ??
Question 2 : Most of the breeze examples are suggesting one SaveChanges method that give you all the entities that were changed and it will persist it at once. What if i want to trigger some business logic before Add,Update and Delete. i want to call me AddSomething service method and want to have a particular type of entity being sent to AddSomething and run some business logic before persistence. How can i put it together.
my code looksl ike
[BreezeController]//This is the controller
public class BreezeController : ApiController
{
private readonly ISomeService someService;
public BreezeController(ISomeService someService)
{
this.someService = someService;
}
// ~/breeze/todos/Metadata
[HttpGet]
public string Metadata()
{
return someService.MetaData();
}
// ~/breeze/todos/Todos
// ~/breeze/todos/Todos?$filter=IsArchived eq false&$orderby=CreatedAt
[HttpGet]
public IQueryable<Node> Nodes()
{
return nodesService.GetAllNodes().AsQueryable();
}
// ~/breeze/todos/SaveChanges
//[HttpPost]
//public SaveResult SaveChanges(JObject saveBundle)
//{
// return _contextProvider.SaveChanges(saveBundle);
//}
Below is the service
public class SomeService : BaseService, ISomeService
{
private readonly IUow Uow;
public SomeService(IUow Uow)
: base(Uow)
{
this.Uow = Uow;
}
public IEnumerable<Something> GetAllNodes()
{
return Uow.Somethings.GetAll();
}
}
every service can expose one property through base. that is actually the meta data
public class BaseService : IBaseService
{
private readonly IUow Uow;
public BaseService(IUow Uow)
{
this.Uow = Uow;
}
public string MetaData()
{
return Uow.MetaData;
}
}
and the my UOW looks like
public class VNUow : IUow, IDisposable
{
public VNUow(IRepositoryProvider repositoryProvider)
{
CreateDbContext();
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
// Code Camper repositories
public IRepository<Something> NodeGroup { get { return GetStandardRepo<Something>(); } }
} }
public IRepository<Node> Nodes { get { return GetStandardRepo<Node>(); } }
/// <summary>
/// Save pending changes to the database
/// </summary>
public void Commit()
{
//System.Diagnostics.Debug.WriteLine("Committed");
DbContext.Context.SaveChanges();
}
public string MetaData // the Name property
{
get
{
return DbContext.Metadata();
}
}
protected void CreateDbContext()
{
// DbContext = new VNContext();
DbContext = new EFContextProvider<VNContext>();
// Load navigation properties always if it is true
DbContext.Context.Configuration.LazyLoadingEnabled = false;
// Do NOT enable proxied entities, else serialization fails
DbContext.Context.Configuration.ProxyCreationEnabled = true;
// Because Web API will perform validation, we don't need/want EF to do so
DbContext.Context.Configuration.ValidateOnSaveEnabled = false;
//DbContext.Configuration.AutoDetectChangesEnabled = false;
// We won't use this performance tweak because we don't need
// the extra performance and, when autodetect is false,
// we'd have to be careful. We're not being that careful.
}
protected IRepositoryProvider RepositoryProvider { get; set; }
private IRepository<T> GetStandardRepo<T>() where T : class
{
return RepositoryProvider.GetRepositoryForEntityType<T>();
}
private T GetRepo<T>() where T : class
{
return RepositoryProvider.GetRepository<T>();
}
private EFContextProvider<VNContext> DbContext { get; set; }
#region IDisposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (DbContext != null)
{
DbContext.Context.Dispose();
}
}
}
#endregion
}
in the end Repository Implementaion looks like
public class EFRepository<T> : IRepository<T> where T : class
{
public EFRepository(EFContextProvider<VNContext> dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
DbContext = dbContext;
DbSet = DbContext.Context.Set<T>();
}
protected EFContextProvider<VNContext> DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public virtual IQueryable<T> GetAll()
{
return DbSet;
}
public virtual IQueryable<T> GetAllEagerLoad(params Expression<Func<T, object>>[] children)
{
children.ToList().ForEach(x => DbSet.Include(x).Load());
return DbSet;
}
public virtual IQueryable<T> GetAllEagerLoadSelective(string[] children)
{
foreach (var item in children)
{
DbSet.Include(item);
}
return DbSet;
}
public virtual IQueryable<T> GetAllLazyLoad()
{
return DbSet;
}
public virtual T GetById(int id)
{
//return DbSet.FirstOrDefault(PredicateBuilder.GetByIdPredicate<T>(id));
return DbSet.Find(id);
}
public virtual T GetByIdLazyLoad(int id, params Expression<Func<T, object>>[] children)
{
children.ToList().ForEach(x => DbSet.Include(x).Load());
return DbSet.Find(id);
}
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Context.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
public virtual void Update(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Context.Entry(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
DbSet.Attach(entity);
}
dbEntityEntry.State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Context.Entry(entity);
if (dbEntityEntry.State != EntityState.Deleted)
{
dbEntityEntry.State = EntityState.Deleted;
}
else
{
DbSet.Attach(entity);
DbSet.Remove(entity);
}
}
public virtual void Delete(int id)
{
var entity = GetById(id);
if (entity == null) return; // not found; assume already deleted.
Delete(entity);
}
}
Much of this question is broad question and answers will be primarily opinion based... that said, here's my two cents: keep it simple. Carefully consider whether you truly need 3, 4 and 5, especially whether you need to implement UoW or the Repository Pattern yourself. The EF DbContext implements both, you could use it in your controllers directly if you wanted.
If you have custom logic that needs to execute prior to savechanges utilize one of the interceptor methods: BeforeSaveEntity or BeforeSaveEntites. Here's the documentation for those methods:
http://www.getbreezenow.com/documentation/contextprovider#BeforeSaveEntity
Breeze supports "Named saves" where you specify the name of the specific server endpoint ( i.e. your service method) on a per save basis. See:
http://www.getbreezenow.com/documentation/saving-changes
This would look something like this on your client.
var saveOptions = new SaveOptions({ resourceName: "CustomSave1" });
em.saveChanges(entitiesToSave, saveOptions).then(function (saveResult) {
// .. do something interesting.
}
and on your server
[HttpPost]
public SaveResult CustomSave1(JObject saveBundle) {
ContextProvider.BeforeSaveEntityDelegate = CustomSave1Interceptor;
return ContextProvider.SaveChanges(saveBundle);
}
private Dictionary<Type, List<EntityInfo>> CustomSave1Interceptor(Dictionary<Type, List<EntityInfo>> saveMap) {
// In this method you can
// 1) validate entities in the saveMap and optionally throw an exception
// 2) update any of the entities in the saveMap
// 3) add new entities to the saveMap
// 4) delete entities from the save map.
// For example
List<EntityInfo> fooInfos;
if (!saveMap.TryGetValue(typeof(Foo), out fooEntities)) {
// modify or delete any of the fooEntites
// or add new entityInfo instances to the fooEntities list.
}
}

how to use selenium with fitnesse

I am creating a small test. In Code behind I have two classes. Pages, LoginPage.
The first part is running. I dont know how to integrate with second part. Currently I am able to open the browser. Also I am trying to use the Page obect model pattern .
Fitnesse code
!|import|
|TestFramework|
!|script|Pages|
|Goto||https://gmail.com|
|LoginPage|CheckRequiredElementsPresent|Pass|
Fixtures
public class Pages
{
string url;
private LoginPage loginPage;
public static void Goto(string url)
{
Browser.Goto(url);
}
}
public class LoginPage
{
static string PageTitle;
[FindsBy(How = How.Id, Using = "TextUsername")]
private static IWebElement username;
[FindsBy(How = How.Id, Using = "TextPassword")]
private static IWebElement password;
[FindsBy(How = How.Id, Using = "_ButtonLogin")]
private static IWebElement submit;
public string IsAtLoginPage()
{
return "";
}
public string CheckRequiredElementsPresent()
{
if (username != null && password != null && submit != null)
{
return "Pass";
}
return "Fail";
}
}
}
You need to do something like below:
Fitnesse Code
!|import|
|TestFramework|
!|script|Pages|
|Goto||https://gmail.com|
|check Required Element|Pass|
You need to call your second class from your Pages class, please see the code changes & fitnesse fixture changes that I've made.
Fixtures
public class Pages
{
string url;
private LoginPage loginPage;
public static void Goto(string url)
{
Browser.Goto(url);
}
// This is what you need to do to refer method of second class.
// This method will be called after Goto method in sequence.
public boolean checkRequiredElement(){
return loginPage.CheckRequiredElementsPresent()
}
}

App Engine JPA Datastore delete entity

im trying to build a google app engine projekt with JPA, JAX-RS and JAX-B. My POST and GET Methods work, but my DELETE method doesn't delete the data.
Resource
#DELETE
#Path("card/{id}")
public void deleteCardById (#PathParam ("id") Long id) {
Service.removeCard(id);
}
Service
public static void removeCard(Long id) {
EntityManager em = EMFService.get().createEntityManager();
Card emp = findCard(id);
if (emp != null) {
em.remove(emp);
}
em.close();
}
public static Card findCard(Long id) {
EntityManager em = EMFService.get().createEntityManager();
Card card = em.find(Card.class, id);
em.close();
return card;
}
Entity
#XmlRootElement
#Entity
public class Card {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String begriff;
String tabu1;
String tabu2;
String tabu3;
public Card(String begriff, String tabu1, String tabu2, String tabu3) {
super();
Begriff = begriff;
Tabu1 = tabu1;
Tabu2 = tabu2;
Tabu3 = tabu3;
}
public Card() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getBegriff() {
return Begriff;
}
public void setBegriff(String begriff) {
Begriff = begriff;
}
public String getTabu1() {
return Tabu1;
}
public void setTabu1(String tabu1) {
Tabu1 = tabu1;
}
public String getTabu2() {
return Tabu2;
}
public void setTabu2(String tabu2) {
Tabu2 = tabu2;
}
public String getTabu3() {
return Tabu3;
}
public void setTabu3(String tabu3) {
Tabu3 = tabu3;
}
#Override
public String toString() {
return "Card [Begriff=" + Begriff + ", Tabu1=" + Tabu1 + ", Tabu2="
+ Tabu2 + ", Tabu3=" + Tabu3 + "]";
}
When i Debug the app it gives the correct Object to the remove function. But it just don't remove the data ...
You mean you're using v1 of the GAE JPA plugin, and you don't bother putting a transaction around your remove (so the remove is delayed until the next transaction ... which never happens)?
Obviously you could either put a transaction around the remove, or better still you use v2 of the GAE JPA plugin
I was facing similar issue too. the JPA delete actually deletes the entity in the datastore,but it doesn't delete the entity from the JPA Cache.. You page is actually using the JPA Cached result list to display..
The way I used to resolve the issue is to have the JPA Cache cleared every time after a delete.
Sample Code would be something like this:
EM.getTransaction().begin();
EM.remove(current_record);
EM.getTransaction().commit();
EM.getEntityManagerFactory().getCache().evictAll();
ok i think i should write it like this
*edit the problem was the findCard function, i think because of the secone instance of the EntityManager. I chnaged it without using this method to this and now it works.
public static void removeCard(Long id) {
EntityManager em = EMFService.get().createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
Card card = em.find(Card.class, id);
if (card != null) {
em.remove(card);
}
tx.commit();
} finally {
if (tx.isActive()) {
tx.rollback();
}
em.close();
}
}

create adatabase through CreateDatabaseDocument() function

I want to create a database in ravendb , I used EnsureDatabaseExist() function. I am not able to use the function CreateDatabaseDocument() from namespace Raven.Client.Extensions and class is public static class MultiDatabase{} in my c# code. Intellisense in vs2010 not showing this function.
my code is :enter code here
public CreateDatabaseOpResult CreateDatabase(ConnectionOperationResult connection,string name)
{
DocumentDatabase database;
CreateDatabaseOpResult databaseOperationResult = new CreateDatabaseOpResult();
if (connection.IsOperationSuccessfull == true)
{
try
{
var doc = connection.documentStore.DatabaseCommands.ForDefaultDatabase();
var docId = doc.Get("Raven/Databases/" + name);
if (docId == null)
{
//static class
//multidatabase
connection.documentStore.DatabaseCommands.EnsureDatabaseExists(name);
}
else
{
databaseOperationResult.IsOperationSuccessfull = false;
throw new ArgumentException("Database already exists");
}
databaseOperationResult.IsOperationSuccessfull = true;
databaseOperationResult.database = database;
}
//and i want to use this function from
namespace Raven.Client.Extensions
{
///<summary>
/// Methods to create mutli tenants databases
///</summary>
public static class MultiDatabase
{
public static RavenJObject CreateDatabaseDocument(string name)
{
AssertValidName(name);
var doc = RavenJObject.FromObject(new DatabaseDocument
{
Settings =
{
{"Raven/DataDir", Path.Combine("~", Path.Combine("Tenants", name))}
}
});
doc.Remove("Id");
return doc;
}
thanks in advance...:)
CreateDatabase is an internal method which just returned the database document. EnsureDatabaseExist used this method and also stores that document if it doesn't exists.
You should use EnsureDatabaseExist method.

Resources