JPA in a JavaFX Context - jpa

So far I used JPA in a managed container but currently I'm working on a desktop application with JavaFX and JPA and I have to manage the transactions. I have an application that has multiple javafx windows:
First window: It shows some projects in a list (entry)
When you click on an entry it shows some details of that project (details view)
In the details view you can add some information about that project (details form)
First of all I create a project that will be listed in the entry view. Then I enter the details view of that project. In the details view I add a new entry by filling out the third view. I click enter and the details view gets updated with that information. Then I leave the details view and I have a kind of summary in the entry page about the whole project. This all works fine. Then I enter the details view again and edit some stuff in the form (step 3). When I click ok the details view gets updated. Then I leave the details view to return to the entry page but the summary is not updated.
So my problem actually is that the entry page is not updated when the details are updated (the very first time when I create the details the entry page is updated correctly)
Some code...
The entry page [1] opens the details page like this:
protected void showActivities(Project project, Window window) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("ProjectActivities.fxml"));
Stage stage = ModalDialogHelper.createNewModal("Project Activity Log", loader, window);
ProjectActivityController pac = loader.getController();
project = projectDataService.detach(project);
pac.setProject(project);
pac.onPostLoad();
stage.showAndWait();
projectDataService.merge(project);
onReload();
} catch (Exception e) {
e.printStackTrace();
}
}
The details page (ProjectActivities.fxml [2]) opens a the form [3]e in a new window like this (triggered by a button on the window):
#FXML
private void openActivityEditor(ActionEvent event) {
createActivityEditor(((Node) event.getSource()).getScene().getWindow(), null);
}
protected void createActivityEditor(Window window, Activity activity) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("ActivityLogForm.fxml"));
Stage stage = ModalDialogHelper.createNewModal("Create A New Activity...", loader, window);
ActivityLogController controller = loader.getController();
controller.setProject(project);
controller.setActivity((activity != null) ? activityDataService.detach(activity) : activity);
controller.onPostLoad();
stage.showAndWait();
if (activity != null) {
activity = activityDataService.merge(activity);
}
onReload();
} catch (IOException e) {
e.printStackTrace();
}
}
I submit the form [3] (ActivityLogForm.fxml) with this piece of code:
#FXML
private void saveActivity(ActionEvent event) {
if (activity == null) {
activity = new Activity();
activity.setProject(project);
project.getActivities().add(activity);
} else {
activityDataService.merge(activity);
}
activity.setBegin(getBegin());
activity.setStop(getStop());
if (activity.getLog() == null) {
Log log = new Log();
activity.setLog(log);
}
if (details != null) {
activity.getLog().setDetails(details.getText());
}
if (activity.getId() > 0) {
activity = activityDataService.merge(activity);
} else {
activityDataService.persist(activity);
}
activityDataService.detach(activity);
ModalDialogHelper.close(((Node) event.getSource()).getScene().getWindow());
}
Some more infos...
The entry view [1] shows a list of projects inside a VBox. When I click on a project a new window will be opened (details view [2]) and the clicked project will be passed to the details view controller to that view. In the details view one can open a new form (window [3]) to enter the details. By committing the form the details get updated as wanted in the details view [2]. Then I exit the details view and the main view [1] is updated as expected. Then I go back into the details of the very same project and want to change some stuff in the details form [3] (it's the same form as for creating new details as before). I submit the changes and the details view [2] gets updated correctly but then I exit the details view and get back to the main view [1]. But now in this view I don't see the changes I just made but they are written to the datastore.
Update
I forgot to say that i'm using EclipseLink and here's my generic dataservice:
public abstract class AbstractDataService<T> {
protected EntityManager entityManager;
protected int pageSize;
protected Class<T> type;
public AbstractDataService(Class<T> clazz) {
this.type = clazz;
init();
}
protected void init() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("ttUnit");
entityManager = factory.createEntityManager();
setPageSize(Integer.parseInt(Resources.getString("settings.pagination.default"), 10));
}
public T find(Object o) {
return entityManager.find(type, o);
}
public List<T> findAll() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> query = builder.createQuery(type);
Root<T> entities = query.from(type);
return entityManager.createQuery(query.select(entities)).getResultList();
}
public List<T> getPage(int page) {
if (isPageOutOfBounds(page)) {
page = correctPage(page);
}
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> query = builder.createQuery(type);
Root<T> entities = query.from(type);
return entityManager.createQuery(query.select(entities)).setFirstResult(getFirstResult(page))
.setMaxResults(pageSize).getResultList();
}
private boolean isPageOutOfBounds(int page) {
int pageCount = getPages();
return page < 0 || (pageCount > 0 && page > pageCount);
}
private int correctPage(int page) {
int pageCount = getPages();
if (page < 0) {
page = 1;
}
if (pageCount > 0) {
while (page > pageCount) {
page--;
}
} else {
// reset to the first page
page = 1;
}
return page;
}
public int getPages() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> query = builder.createQuery(Long.class);
Expression<Long> entities = builder.count(query.from(type));
long count = entityManager.createQuery(query.select(entities)).getSingleResult();
int pageCount = (int) Math.ceil((double) count / (double) pageSize);
return pageCount;
}
public int getFirstResult(int page) {
return (page - 1) * pageSize;
}
public T merge(T obj) {
try {
entityManager.getTransaction().begin();
return entityManager.merge(obj);
} finally {
entityManager.getTransaction().commit();
}
}
public void persist(T obj) {
try {
entityManager.getTransaction().begin();
entityManager.persist(obj);
} finally {
entityManager.getTransaction().commit();
}
}
public void remove(T obj) {
try {
entityManager.getTransaction().begin();
entityManager.remove(obj);
} finally {
entityManager.getTransaction().commit();
}
}
public void flush() {
try {
entityManager.getTransaction().begin();
entityManager.flush();
} finally {
entityManager.getTransaction().commit();
}
}
public T detach(T obj) {
entityManager.detach(obj);
return obj;
}
public void clear() {
entityManager.clear();
}
/**
* #return the pageSize
*/
public int getPageSize() {
return pageSize;
}
/**
* #param pageSize
* the pageSize to set
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
}
Here's the data model that I'm using:
Project
| 1 (- activities (Cascade: ALL))
|
| 0..n
Activity
- project (Cascade: MERGE, DETACH)

I've found the solution for it. The problem was that when I created a new activity, the activity passed to the ActivityLogController in createActivityEditor was null. Which means that I only merge the entity when it has been edited but I did not merge the project if a new activity is created:
protected void createActivityEditor(Window window, Activity activity) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("ActivityLogForm.fxml"));
Stage stage = ModalDialogHelper.createNewModal("Create A New Activity...", loader, window);
ActivityLogController controller = loader.getController();
controller.setProject(project);
controller.setActivity((activity != null) ? activityDataService.detach(activity) : activity);
controller.onPostLoad();
stage.showAndWait();
if (activity != null) {
// re-attach the existing activity
activity = activityDataService.merge(activity);
} else {
// the activity did not yet exist but the project needs to be
// merged with the new activity
project = projectDataService.merge(project);
}
onReload();
} catch (IOException e) {
e.printStackTrace();
}
}
Like that the project is synchronized with the underlying database and is aware of that new activity. So further changes will be merged because the activity is not null and the project property in the Activity Entity is marked as cascade = MERGE.
Maybe it helps someone with similar issues and thanks for your help

Related

Update SyncFusion Grid after backend data source has changed

I have a SyncFusion data grid tied to a backend SQL database. My crud actions are called through custom buttons that call a dialog box.
This works nicely except that the grid is not updated with the backend data after an add/edit/delete. I have tired refreshing the grid but that doesn't seem to work.
What do I need to do?
MyTemplates.razor
#page "/My_Templates"
#using WireDesk.Models
#inject IWireDeskService WireDeskService
<ReusableDialog #ref="dialog"></ReusableDialog>
<SfGrid #ref="Grid" DataSource="#Templates" TValue="Template" AllowSorting="true" Toolbar="ToolbarItems">
<GridEvents OnToolbarClick="OnClicked" TValue="Template"></GridEvents>
<GridColumns>
<GridColumn Field=#nameof(Template.Owner) HeaderText="Owner" ValidationRules="#(new ValidationRules { Required = true })" Width="120"></GridColumn>
<GridColumn Field=#nameof(Template.Users) HeaderText="Users" TextAlign="TextAlign.Left" Width="130"></GridColumn>
<GridColumn Field=#nameof(Template.Description) HeaderText="Description" TextAlign="TextAlign.Left" Width="130"></GridColumn>
<GridColumn Field=#nameof(Template.FundType) HeaderText="Fund Type" TextAlign="TextAlign.Left" Width="120"></GridColumn>
</GridColumns>
</SfGrid>
#code{
//Instantiate objects
SfGrid<Template> Grid { get; set; }
ReusableDialog dialog;
//Instantiate toolbar and toolbar items
private List<Object> ToolbarItems = new List<Object>()
{
new ItemModel() { Text = "Create New Template", TooltipText = "Add", PrefixIcon = "e-icons e-update", Id = "Add", },
new ItemModel() { Text = "Edit Template", TooltipText = "Edit", PrefixIcon = "e-icons e-update", Id = "Edit"}
};
//Instatiate records
public IEnumerable<Template> Templates { get; set; }
//Instantiate Records
protected override void OnInitialized()
{
Templates = WireDeskService.GetTemplates();
}
//Handle toolbar clicks
public async Task OnClicked(Syncfusion.Blazor.Navigations.ClickEventArgs Args)
{
//Create Record
if (Args.Item.Id == "Add")
{
Args.Cancel = true; //Prevent the default action
dialog.Title = "This is the Add Title";
dialog.Text = "This is the add text";
dialog.template = new Template();
dialog.OpenDialog();
WireDeskService.InsertTemplate(dialog.template);
//Grid.CallStateHasChanged(); Doesn't Work
//Templates = WireDeskService.GetTemplates(); Doesn't Work
}
//Edit Records
if (Args.Item.Id == "Edit")
{
Args.Cancel = true; //Prevent the default action
var selected = await Grid.GetSelectedRecordsAsync();
if (selected.Count > 0)
{
//Call Dialog Box Here
dialog.Title = "This is the Edited Title";
dialog.Text = "This is the edited text";
dialog.template = selected[0];
dialog.OpenDialog();
WireDeskService.UpdateTemplate(dialog.template.TemplateId, dialog.template);
Grid.CallStateHasChanged();
}
}
}
}
<style>
.e-altrow {
background-color: rgb(182 201 244);
}
</style>
WireDeskService.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WireDesk.Models
{
public class WireDeskService : IWireDeskService
{
private WireDeskContext _context;
public WireDeskService(WireDeskContext context)
{
_context = context;
}
public void DeleteTemplate(long templateId)
{
try
{
Template ord = _context.Templates.Find(templateId);
_context.Templates.Remove(ord);
_context.SaveChanges();
}
catch
{
throw;
}
}
public IEnumerable<Template> GetTemplates()
{
try
{
return _context.Templates.ToList();
}
catch
{
throw;
}
}
public void InsertTemplate(Template template)
{
try
{
_context.Templates.Add(template);
_context.SaveChanges();
}
catch
{
throw;
}
}
public Template SingleTemplate(long id)
{
throw new NotImplementedException();
}
public void UpdateTemplate(long templateId, Template template) {
try
{
var local = _context.Set<Template>().Local.FirstOrDefault(entry => entry.TemplateId.Equals(template.TemplateId));
// check if local is not null
if (local != null)
{
// detach
_context.Entry(local).State = EntityState.Detached;
}
_context.Entry(template).State = EntityState.Modified;
_context.SaveChanges();
}
catch
{
throw;
}
}
void IWireDeskService.SingleTemplate(long templateId)
{
throw new NotImplementedException();
}
}
}
We have analyzed your query and we understand that you want to save the changes in your database when data is bound to Grid using DataSource property. We would like to inform you that when data is bound to Grid component using DataSource property, CRUD actions needs to handled using ActionEvents (OnActionComplete and OnActionBegin).
OnActionBegin event – Will be triggered when certain action gets initiated.
OnActionComplete event – Will be triggered when certain action gets completed.
We suggest you to achieve your requirement to save the changes in database using OnActionBegin event of Grid when RequestType is Save. While saving the records, irrespective of Add or Update action. OnActionBegin event will be triggered when RequestType as Save. In that event we can update the changes into database.
Since the Add and Edit actions share the same RequestType “Save”, we can differentiate the current action using Args.Action argument. Similarly we request you fetch the updated data from your database and bind to Grid in OnActionComplete event of Grid.
Refer the below code example.
<SfGrid #ref="Grid" DataSource="#GridData" Toolbar="#(new List<string> { "Add", "Edit", "Delete", "Cancel", "Update" })" AllowFiltering="true" AllowSorting="true" AllowPaging="true">
<GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true"></GridEditSettings>
<GridEvents OnActionBegin="OnBegin" OnActionComplete="OnComplete" TValue="Order"></GridEvents>
<GridColumns>
<GridColumn Field=#nameof(Order.OrderID) HeaderText="Order ID" IsIdentity="true" IsPrimaryKey="true" TextAlign="TextAlign.Right" Width="120"></GridColumn>
<GridColumn Field=#nameof(Order.CustomerID) HeaderText="Customer Name" Width="150"></GridColumn>
<GridColumn Field=#nameof(Order.EmployeeID) HeaderText="Id" Width="150"></GridColumn>
</GridColumns>
</SfGrid>
#code{
SfGrid<Order> Grid { get; set; }
public IEnumerable<Order> GridData { get; set;}
protected override void OnInitialized()
{
GridData = OrderData.GetAllOrders().ToList();
}
public void OnComplete(ActionEventArgs<Order> Args)
{
if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Save || Args.RequestType == Syncfusion.Blazor.Grids.Action.Refresh)
{
GridData = OrderData.GetAllOrders().ToList(); // fetch updated data from service and bind to grid datasource property
}
}
public void OnBegin(ActionEventArgs<Order> Args)
{
if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Save) // update the changes in Actionbegine event
{
if (Args.Action == "Add")
{
//Args.Data contain the inserted record details
//insert the data into your database
OrderData.AddOrder(Args.Data);
}
else
{
//Args.Data contain the updated record details
//update the data into your database
OrderData.UpdateOrder(Args.Data);
}
} else if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Delete)
{
OrderData.DeleteOrder(Args.Data.OrderID); // delete the record from your database
}
}
}
Refer our UG documentation for your reference
https://blazor.syncfusion.com/documentation/datagrid/events/#onactionbegin
https://blazor.syncfusion.com/documentation/datagrid/events/#onactioncomplete

How to pass argument in class that extends "EditorPart" from handler class to affect "createPartControl" UI creation

I have 2 problems.
1) Command handler not responding for EditorPart
2) How to pass argument to a class that extends "EditorPart" to affect "createPartControl" method for UI creation.
Please have a look below in my code for better understanding. I have created command handler for Editor but my handler is not responding as expected. I want to have the selected file path in the package explorer and pass this file path value to the class that extends EditorPart in order to create UI based on this selected file.
Handler.java
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
// get the page
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
IWorkbenchPage page = window.getActivePage();
// get the selection
ISelection selection = HandlerUtil.getCurrentSelection(event);
IStructuredSelection sel = (IStructuredSelection) selection;
Object selObj = sel.getFirstElement();
if (selObj instanceof IResource) {
resource = (IResource) selObj;
project = resource.getProject();
location = project.getLocation();
}else {
IAdaptable adaptable = (IAdaptable)selObj;
Object adapter = adaptable.getAdapter(IResource.class);
resource = (IResource) adapter;
project = resource.getProject();
location = project.getLocation();
}
TaskEditorInput input = new TaskEditorInput();
try {
page.openEditor(input, "launcher.ChartEditor");
} catch (PartInitException e) {
e.printStackTrace();
}
return null;
}
class that extends EditorPart
#Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
setSite(site);
setInput(input);
setPartName("ChartEditor");
}
public void createPartControl(Composite _parent) {
}
public void createChart(String filePath) {
dataset = chart1.createDataset(filePath);
try {
chart = chart1.createChart(dataset);
frame = new ChartComposite(parent, SWT.NONE, chart, true);
frame.pack();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I want pass the value of selected filepath in this createChart(String filePath) method from handler class. How can i do this? Please help me.
Add the value you want to pass to your class implementing IEditorInput (TaskEditorInput in your case). The editor input is given to the editor init method so you can get the value there:
#Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
if (input instanceof TaskEditorInout) {
TaskEditorInput taskInput = (TaskEditorInput)input;
// TODO save value for createPartControl
}
setSite(site);
setInput(input);
setPartName("ChartEditor");
}
To be sure to get the resource corresponding to a selection you need to use the platform adapter manager. On modern versions of Eclipse you can use
IStructuredSelection sel = HandlerUtil.getCurrentStructuredSelection(event);
IResource resource = Adapters.adapt(sel.getFirstElement(), IResource.class);

How can we get the item on which i am doing the drop on a treeviewer

I have created a jface treeviewer and i am adding drag and drop of elements into the treeviewer.So the items should be added on the the subchild of a tree.How can i get the subchildname on which i am dropping a element.
for eg:
tree->
A->
1
2
B
C
so when I drag and drop on 1 it should get the selecteditem as 1 how can we do it.
the code for drop is as follows
int operationsn = DND.DROP_COPY | DND.DROP_MOVE;
Transfer[] transferType = new Transfer[]{TestTransfer.getInstance()};
DropTarget targetts = new DropTarget(treeComposite, operationsn);
targetts.setTransfer(new Transfer[] { TestTransfer.getInstance() });
targetts.addDropListener(new DropTargetListener() {
public void dragEnter(DropTargetEvent event) {
System.out.println("dragEnter in target ");
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
}
public void dragOver(DropTargetEvent event) {
System.out.println("dragOver in target ");
event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
}
public void dragOperationChanged(DropTargetEvent event) {
System.out.println("dragOperationChanged in target ");
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
}
public void dragLeave(DropTargetEvent event) {
System.out.println("dragLeave in target ");
}
public void dropAccept(DropTargetEvent event) {
System.out.println("dropAccept in target ");
}
public void drop(DropTargetEvent event) {
//if (textTransfer.isSupportedType(event.currentDataType))
if (event.data != null) {
Test tsType = (Test) event.data;
addItem(tsType);
System.out.println("test step name is" +tsType);
}
}
});
Here in the addItem function I have written the code to add item to the treeviewer on the selecteditem.but while dropping the item I am not able to select the item so how can we selected the item while dropping the elements into the tree.
When using JFace Viewers you can use the JFace ViewDropAdapter class rather than DropTargetListener.
This class does more work for you and has a getCurrentTarget() method to return the current target element.
More details on this here

Unstable application uses SqlDependency. Several states and errors

I have a windows application using SqlDependency running at separated thread pool, this application represents a log monitor UI get the latest rows added in a specific table in the database and view it in a DataGridView. You can see the application source code from this LINK, or follow this script.
const string tableName = "OutgoingLog";
const string statusMessage = "{0} changes have occurred.";
int changeCount = 0;
private static DataSet dataToWatch = null;
private static SqlConnection connection = null;
private static SqlCommand command = null;
public frmMain()
{
InitializeComponent();
}
private bool CanRequestNotifications()
{
// In order to use the callback feature of the
// SqlDependency, the application must have
// the SqlClientPermission permission.
try
{
SqlClientPermission perm = new SqlClientPermission(PermissionState.Unrestricted);
perm.Demand();
return true;
}
catch
{
return false;
}
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
// This event will occur on a thread pool thread.
// Updating the UI from a worker thread is not permitted.
// The following code checks to see if it is safe to
// update the UI.
ISynchronizeInvoke i = (ISynchronizeInvoke)this;
// If InvokeRequired returns True, the code
// is executing on a worker thread.
if (i.InvokeRequired)
{
// Create a delegate to perform the thread switch.
OnChangeEventHandler tempDelegate = new OnChangeEventHandler(dependency_OnChange);
object[] args = { sender, e };
// Marshal the data from the worker thread
// to the UI thread.
i.BeginInvoke(tempDelegate, args);
return;
}
// Remove the handler, since it is only good
// for a single notification.
SqlDependency dependency = (SqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
// At this point, the code is executing on the
// UI thread, so it is safe to update the UI.
++changeCount;
lblChanges.Text = String.Format(statusMessage, changeCount);
// Reload the dataset that is bound to the grid.
GetData();
}
AutoResetEvent running = new AutoResetEvent(true);
private void GetData()
{
// Start the retrieval of data on another thread to let the UI thread free
ThreadPool.QueueUserWorkItem(o =>
{
running.WaitOne();
// Empty the dataset so that there is only
// one batch of data displayed.
dataToWatch.Clear();
// Make sure the command object does not already have
// a notification object associated with it.
command.Notification = null;
// Create and bind the SqlDependency object
// to the command object.
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
adapter.Fill(dataToWatch, tableName);
try
{
running.Set();
}
finally
{
// Update the UI
dgv.Invoke(new Action(() =>
{
dgv.DataSource = dataToWatch;
dgv.DataMember = tableName;
//dgv.FirstDisplayedScrollingRowIndex = dgv.Rows.Count - 1;
}));
}
}
});
}
private void btnAction_Click(object sender, EventArgs e)
{
changeCount = 0;
lblChanges.Text = String.Format(statusMessage, changeCount);
// Remove any existing dependency connection, then create a new one.
SqlDependency.Stop("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
SqlDependency.Start("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
if (connection == null)
{
connection = new SqlConnection("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
}
if (command == null)
{
command = new SqlCommand("select * from OutgoingLog", connection);
//SqlParameter prm =
// new SqlParameter("#Quantity", SqlDbType.Int);
//prm.Direction = ParameterDirection.Input;
//prm.DbType = DbType.Int32;
//prm.Value = 100;
//command.Parameters.Add(prm);
}
if (dataToWatch == null)
{
dataToWatch = new DataSet();
}
GetData();
}
private void frmMain_Load(object sender, EventArgs e)
{
btnAction.Enabled = CanRequestNotifications();
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
SqlDependency.Stop("Server=.; Database=SMS_Tank_Log;UID=sa;PWD=hana;MultipleActiveResultSets=True");
}
The problem:
I have many situations of errors, (images in the first comment)
(No. 1):
I got this error dialog, and I don't know its reason.
(No. 2):
I got nothing in my grid view (No errors, and no data).
(No. 3):
I got only columns names and no rows, although the table has rows.
I need help please.
I may be wrong but a DataSet does not seem to have notification capability so the DataGridView may be surprised if you change it behind its back.
You could try to explicitly show your're changing the data source by first setting it to null:
dgv.DataSource = null;
dgv.DataSource = dataToWatch;
dgv.DataMember = tableName;
It's worth a try...

StackoverflowException while using SqlDependencies with Ef Framework

I would like to get some feedback about using SqlDependencies with EF Framework 4.0. I have currently implemented a scenario using ObjectQuery in combination with toStraceString() to generate SqlDependency.
Im getting a StackoverflowException somewhere in Entity Framework source code when doing refresh store wins. I thought this error would somewhere in my code, but i cannot find it.
I made up a small example of what i want to do:
public partial class MainWindow : Window
{
private SqlDependency _sqldep;
public delegate void DataChanged(string test);
TestEntities m = new TestEntities();
SqlCommand _cmd;
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
//m.Connection.Open();
SqlDependency.Start(((System.Data.EntityClient.EntityConnection)m.Connection).StoreConnection.ConnectionString);
var query = m.User.AsQueryable<User>();
string query_str = m.User.ToTraceString();
SqlConnection con = new SqlConnection(((System.Data.EntityClient.EntityConnection)m.Connection).StoreConnection.ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand(query_str, con);
_cmd = cmd;
_sqldep = new SqlDependency(cmd);
_sqldep.OnChange += dependency_OnChange;
cmd.ExecuteReader();
this.Users = m.User;
}
SqlDependency dependency;
// Bei Änderung am gegebenen SQL-Statement
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
dependency = (SqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
NotifierOnDataChanged(string.Empty);
dependency.OnChange += dependency_OnChange;
}
private void NotifierOnDataChanged(string bla)
{
try
{
m.Refresh(System.Data.Objects.RefreshMode.StoreWins, m.User);
}
catch (System.Exception ex)
{
System.Windows.MessageBox.Show(ex.Message, "Fehler");
}
}
private IEnumerable<User> _users;
public IEnumerable<User> Users
{
get { return _users; }
set { _users = value; }
}
}
I'm getting my StackoverflowException at NotifierOnDataChanged -> Refresh