In RefreshScope, why should we add the processing logic of getClass() when receiving the ContextRefreshedEvent notification - spring-cloud

In org.springframework.cloud.context.scope.refresh.RefreshScope, the logic for processing the ContextRefreshedEvent notification is as follows:
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
start(event);
}
public void start(ContextRefreshedEvent event) {
if (event.getApplicationContext() == this.context && this.eager
&& this.registry != null) {
eagerlyInitialize();
}
}
private void eagerlyInitialize() {
for (String name : this.context.getBeanDefinitionNames()) {
BeanDefinition definition = this.registry.getBeanDefinition(name);
if (this.getName().equals(definition.getScope())
&& !definition.isLazyInit()) {
Object bean = this.context.getBean(name);
// question 1
if (bean != null) {
// question 2
bean.getClass();
}
}
}
}
Question 1: If the bean does not exist, an exception will be thrown when the getBean method is executed. Why do we need to judge whether the bean is null?
Question 2: It seems meaningless to execute bean.getClass(), but why do you do it?
I hope someone can answer the above two questions. Thanks.

Related

How to check if a visited node is in if part or else part of IfStatement node in Eclipse JDT parsing?

When I visit a MethodInvocation node during AST traversal, I want to know if it lies in the IfStatement then part or else part or in the expression part. The then part can be a complete block of code but I think my code is handling only a single then statement.
Here is the code snippet for visiting a method invocation
#Override
public boolean visit(MethodInvocation node)
{
StructuralPropertyDescriptor location = node.getLocationInParent();
setNodeRegion(location);
Here is how I want to set flags for each region of IfStatement
private void setNodeRegion(StructuralPropertyDescriptor location) {
if(location == IfStatement.EXPRESSION_PROPERTY ||
location == IfStatement.THEN_STATEMENT_PROPERTY)
{
ParseContextAction.ifBlockRegion = true;
}
else
{
if(location == IfStatement.ELSE_STATEMENT_PROPERTY)
{
ParseContextAction.elseBlockRegion = true;
}
else
{
if(location == CatchClause.BODY_PROPERTY)
{
ParseContextAction.catchBlockRegion = true;
}
else
{
ParseContextAction.basicBlockRegion = true;
}
}
}
}
If you use visit(IfStatement node) instead of visit(MethodInvocation node), you can visit both the then (getThenStatement()) and the else (getElseStatement()) branch with a separate visitor:
#Override
public boolean visit(IfStatement node) {
Statement thenBranch = node.getThenStatement();
if (thenBranch != null) {
thenBranch.accept(new ASTVisitor(false) {
#Override
public boolean visit(MethodInvocation node) {
// handle method invocation in the then branch
return true; // false, if nested method invocations should be ignored
}
}
}
Statement elseBranch = node.getElseStatement();
if (elseBranch != null) {
elseBranch.accept(new ASTVisitor(false) {
#Override
public boolean visit(MethodInvocation node) {
// handle method invocation in the else branch
return true; // false, if nested method invocations should be ignored
}
}
}
return true; // false, if nested if statements should be ignored
}

ABP EF Core multiple DbContext access in IDomainService throws transaction error

The specified transaction is not associated with the current connection. Only transactions associated with the current connection may be used.
How do I use multiple DbContext in one transaction?
Update 1
If I use ExistingConnection,
then all the DbContext will use the same connection string.
Did I add multiple DbContext in the wrong way?
In EntityFrameworkModule:
public override void PreInitialize()
{
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
Configuration.Modules.AbpEfCore().AddDbContext<BPDbContext>(options =>
{
if (options.ExistingConnection != null)
{
options.DbContextOptions.UseSqlServer(options.ExistingConnection);
}
else
{
options.DbContextOptions.UseSqlServer(configuration.GetConnectionString(ABPCoreConsts.BPConnectionStringName));
}
//options.DbContextOptions.UseSqlServer(
// configuration.GetConnectionString(ABPCoreConsts.BPConnectionStringName));
});
Configuration.Modules.AbpEfCore().AddDbContext<EPlusDBConext>(options =>
{
if (options.ExistingConnection != null)
{
options.DbContextOptions.UseSqlServer(options.ExistingConnection);
}
else
{
options.DbContextOptions.UseSqlServer(configuration.GetConnectionString(ABPCoreConsts.EECPlusConnectionStringName));
}
//options.DbContextOptions.UseSqlServer(
// configuration.GetConnectionString(ABPCoreConsts.EECPlusConnectionStringName));
});
Configuration.Modules.AbpEfCore().AddDbContext<ProjectManageDbContext>(options =>
{
if (options.ExistingConnection != null)
{
options.DbContextOptions.UseSqlServer(options.ExistingConnection);
}
else
{
options.DbContextOptions.UseSqlServer(configuration.GetConnectionString(ABPCoreConsts.PMConnectionStringName));
}
//options.DbContextOptions.UseSqlServer(
// configuration.GetConnectionString(ABPCoreConsts.PMConnectionStringName));
});
RegisterGenericRepositories();
}
Update 2
I got it to work by implementing IConnectionStringResolver for custom connections:
public class MyDBConnectionStringResolver : DefaultConnectionStringResolver
{
public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
{
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
switch (args["DbContextType"].ToString())
{
case "ABPCore.EPlusDBConext":
return configuration.GetConnectionString(ABPCoreConsts.EECPlusConnectionStringName);
case "ABPCore.BPDbContext":
return configuration.GetConnectionString(ABPCoreConsts.BPConnectionStringName);
case "ABPCore.ProjectManageDbContext":
return configuration.GetConnectionString(ABPCoreConsts.PMConnectionStringName);
}
return string.Empty;
}
}
Don't forget to replace service in EntityFrameworkModule's PreInitialize method:
Configuration.ReplaceService<IConnectionStringResolver, MyDbConnectionStringResolver>(DependencyLifeStyle.Transient);
Add this in *DbContextConfigurer.cs:
public static void Configure(DbContextOptionsBuilder<*DbContext> builder, DbConnection connection)
{
builder.UseSqlServer(connection);
}
Change this in *EntityFrameworkModule.cs:
public override void PreInitialize()
{
if (!SkipDbContextRegistration)
{
Configuration.Modules.AbpEfCore().AddDbContext<*DbContext>(options =>
{
if (options.ExistingConnection != null)
{
options.DbContextOptions.UseSqlServer(options.ExistingConnection);
}
else
{
options.DbContextOptions.UseSqlServer(options.ConnectionString);
}
});
}
}
Reference: https://github.com/aspnetboilerplate/module-zero-core-template/commit/da522e76ca2ecefdb7670f009f78575c5b97b4a0
Important
If each DbContext has its own connection string, you need to implement IConnectionStringResolver as explained here and replace the service:
Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>(DependencyLifeStyle.Transient);

LoadException with FXML created with Scene Builder 2.0

I got a problem that i absolutly cant solve on my own because i have just started using JAVA FX. I get a nasty javafx.fxml.LoadException: , but i have done exactly like a guide (http://docs.oracle.com/javafx/scenebuilder/1/get_started/jsbpub-get_started.htm), but i cant get my Main to run. This is the console:
ant -f P:\\FXML\\IssueTrackingLite jfxsa-run
init:
deps-jar:
Created dir: P:\FXML\IssueTrackingLite\build
Updating property file: P:\FXML\IssueTrackingLite\build\built-jar.properties
Created dir: P:\FXML\IssueTrackingLite\build\classes
Created dir: P:\FXML\IssueTrackingLite\build\empty
Created dir: P:\FXML\IssueTrackingLite\build\generated-sources\ap-source-output
Compiling 6 source files to P:\FXML\IssueTrackingLite\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.6
1 warning
Copying 4 files to P:\FXML\IssueTrackingLite\build\classes
compile:
Detected JavaFX Ant API version 1.3
Launching <fx:jar> task from C:\Program Files\Java\jdk1.8.0\jre\..\lib\ant-javafx.jar
Warning: From JDK7u25 the Codebase manifest attribute should be used to restrict JAR repurposing.
Please set manifest.custom.codebase property to override the current default non-secure value '*'.
Launching <fx:deploy> task from C:\Program Files\Java\jdk1.8.0\jre\..\lib\ant-javafx.jar
jfx-deployment-script:
jfx-deployment:
jar:
Copying 12 files to P:\FXML\IssueTrackingLite\dist\run910302418
jfx-project-run:
Executing P:\FXML\IssueTrackingLite\dist\run910302418\IssueTrackingLite.jar using platform C:\Program Files\Java\jdk1.8.0\jre/bin/java
before ........!
IssueTrackingLiteController.initialize
août 11, 2014 12:24:01 PM issuetrackinglite.Main start
GRAVE: null
javafx.fxml.LoadException:
file:/P:/FXML/IssueTrackingLite/dist/run910302418/IssueTrackingLite.jar!/issuetrackinglite/IssueTrackingLite.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2595)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3191)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3164)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3140)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3120)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3113)
at issuetrackinglite.Main.start(Main.java:55)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
at issuetrackinglite.IssueTrackingLiteController.configureTable(IssueTrackingLiteController.java:481)
at issuetrackinglite.IssueTrackingLiteController.initialize(IssueTrackingLiteController.java:119)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 19 more
BUILD STOPPED (total time: 50 minutes 46 seconds)
What does it mean and how can I fix it?
the main class:
package issuetrackinglite;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(Main.class, (java.lang.String[])null);
}
#Override
public void start(Stage primaryStage) {
try {
System.out.println(" before ........!");
AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("/issuetrackinglite/IssueTrackingLite.fxml"));
System.out.println(" after .............!");
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Issue Tracking Lite Sample");
primaryStage.show();
} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
my FXML file is in the same path as Main class.
the class Controller:
package issuetrackinglite;
public class IssueTrackingLiteController implements Initializable {
#FXML
Button newIssue;
#FXML
Button deleteIssue;
#FXML
Button saveIssue;
TableView<ObservableIssue> table;
#FXML
TableColumn<ObservableIssue, String> colName;
#FXML
TableColumn<ObservableIssue, IssueStatus> colStatus;
#FXML
TableColumn<ObservableIssue, String> colSynopsis;
#FXML
ListView<String> list;
#FXML
TextField synopsis;
private String displayedBugId; // the id of the bug displayed in the details section.
private String displayedBugProject; // the name of the project of the bug displayed in the detailed section.
#FXML
Label displayedIssueLabel; // the displayedIssueLabel will contain a concatenation of the
// the project name and the bug id.
#FXML
AnchorPane details;
#FXML
TextArea descriptionValue;
ObservableList<String> projectsView = FXCollections.observableArrayList();
TrackingService model = null;
private TextField statusValue = new TextField();
final ObservableList<ObservableIssue> tableContent = FXCollections.observableArrayList();
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rsrcs) {
assert colName != null : "fx:id=\"colName\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert colStatus != null : "fx:id=\"colStatus\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert colSynopsis != null : "fx:id=\"colSynopsis\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert deleteIssue != null : "fx:id=\"deleteIssue\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert descriptionValue != null : "fx:id=\"descriptionValue\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert details != null : "fx:id=\"details\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert displayedIssueLabel != null : "fx:id=\"displayedIssueLabel\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert newIssue != null : "fx:id=\"newIssue\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert saveIssue != null : "fx:id=\"saveIssue\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert synopsis != null : "fx:id=\"synopsis\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert table != null : "fx:id=\"table\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
assert list != null : "fx:id=\"list\" was not injected: check your FXML file 'IssueTrackingLite.fxml'.";
System.out.println(this.getClass().getSimpleName() + ".initialize");
configureButtons();
configureDetails();
configureTable();
connectToService();
if (list != null) {
list.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
list.getSelectionModel().selectedItemProperty().addListener(projectItemSelected);
displayedProjectNames.addListener(projectNamesListener);
}
}
/**
* Called when the NewIssue button is fired.
*
* #param event the action event.
*/
#FXML
public void newIssueFired(ActionEvent event) {
final String selectedProject = getSelectedProject();
if (model != null && selectedProject != null) {
ObservableIssue issue = model.createIssueFor(selectedProject);
if (table != null) {
// Select the newly created issue.
table.getSelectionModel().clearSelection();
table.getSelectionModel().select(issue);
}
}
}
/**
* Called when the DeleteIssue button is fired.
*
* #param event the action event.
*/
#FXML
public void deleteIssueFired(ActionEvent event) {
final String selectedProject = getSelectedProject();
if (model != null && selectedProject != null && table != null) {
// We create a copy of the current selection: we can't delete
// issue while looping over the live selection, since
// deleting selected issues will modify the selection.
final List<?> selectedIssue = new ArrayList<Object>(table.getSelectionModel().getSelectedItems());
for (Object o : selectedIssue) {
if (o instanceof ObservableIssue) {
model.deleteIssue(((ObservableIssue) o).getId());
}
}
table.getSelectionModel().clearSelection();
}
}
/**
* Called when the SaveIssue button is fired.
*
* #param event the action event.
*/
#FXML
public void saveIssueFired(ActionEvent event) {
final ObservableIssue ref = getSelectedIssue();
final Issue edited = new DetailsData();
SaveState saveState = computeSaveState(edited, ref);
if (saveState == SaveState.UNSAVED) {
model.saveIssue(ref.getId(), edited.getStatus(),
edited.getSynopsis(), edited.getDescription());
}
// We refresh the content of the table because synopsis and/or description
// are likely to have been modified by the user.
int selectedRowIndex = table.getSelectionModel().getSelectedIndex();
table.getItems().clear();
displayedIssues = model.getIssueIds(getSelectedProject());
for (String id : displayedIssues) {
final ObservableIssue issue = model.getIssue(id);
table.getItems().add(issue);
}
table.getSelectionModel().select(selectedRowIndex);
updateSaveIssueButtonState();
}
private void configureButtons() {
if (newIssue != null) {
newIssue.setDisable(true);
}
if (saveIssue != null) {
saveIssue.setDisable(true);
}
if (deleteIssue != null) {
deleteIssue.setDisable(true);
}
}
// An observable list of project names obtained from the model.
// This is a live list, and we will react to its changes by removing
// and adding project names to/from our list widget.
private ObservableList<String> displayedProjectNames;
// The list of Issue IDs relevant to the selected project. Can be null
// if no project is selected. This list is obtained from the model.
// This is a live list, and we will react to its changes by removing
// and adding Issue objects to/from our table widget.
private ObservableList<String> displayedIssues;
// This listener will listen to changes in the displayedProjectNames list,
// and update our list widget in consequence.
private final ListChangeListener<String> projectNamesListener = new ListChangeListener<String>() {
#Override
public void onChanged(Change<? extends String> c) {
if (projectsView == null) {
return;
}
while (c.next()) {
if (c.wasAdded() || c.wasReplaced()) {
for (String p : c.getAddedSubList()) {
projectsView.add(p);
}
}
if (c.wasRemoved() || c.wasReplaced()) {
for (String p : c.getRemoved()) {
projectsView.remove(p);
}
}
}
FXCollections.sort(projectsView);
}
};
// This listener will listen to changes in the displayedIssues list,
// and update our table widget in consequence.
private final ListChangeListener<String> projectIssuesListener = new ListChangeListener<String>() {
#Override
public void onChanged(Change<? extends String> c) {
if (table == null) {
return;
}
while (c.next()) {
if (c.wasAdded() || c.wasReplaced()) {
for (String p : c.getAddedSubList()) {
table.getItems().add(model.getIssue(p));
}
}
if (c.wasRemoved() || c.wasReplaced()) {
for (String p : c.getRemoved()) {
ObservableIssue removed = null;
// Issue already removed:
// we can't use model.getIssue(issueId) to get it.
// we need to loop over the table content instead.
// Then we need to remove it - but outside of the for loop
// to avoid ConcurrentModificationExceptions.
for (ObservableIssue t : table.getItems()) {
if (t.getId().equals(p)) {
removed = t;
break;
}
}
if (removed != null) {
table.getItems().remove(removed);
}
}
}
}
}
};
// Connect to the model, get the project's names list, and listen to
// its changes. Initializes the list widget with retrieved project names.
private void connectToService() {
if (model == null) {
model = new TrackingServiceStub();
displayedProjectNames = model.getProjectNames();
}
projectsView.clear();
List<String> sortedProjects = new ArrayList<String>(displayedProjectNames);
Collections.sort(sortedProjects);
projectsView.addAll(sortedProjects);
list.setItems(projectsView);
}
// This listener listen to changes in the table widget selection and
// update the DeleteIssue button state accordingly.
private final ListChangeListener<ObservableIssue> tableSelectionChanged =
new ListChangeListener<ObservableIssue>() {
#Override
public void onChanged(Change<? extends ObservableIssue> c) {
updateDeleteIssueButtonState();
updateBugDetails();
updateSaveIssueButtonState();
}
};
private static String nonNull(String s) {
return s == null ? "" : s;
}
private void updateBugDetails() {
final ObservableIssue selectedIssue = getSelectedIssue();
if (details != null && selectedIssue != null) {
if (displayedIssueLabel != null) {
displayedBugId = selectedIssue.getId();
displayedBugProject = selectedIssue.getProjectName();
displayedIssueLabel.setText( displayedBugId + " / " + displayedBugProject );
}
if (synopsis != null) {
synopsis.setText(nonNull(selectedIssue.getSynopsis()));
}
if (statusValue != null) {
statusValue.setText(selectedIssue.getStatus().toString());
}
if (descriptionValue != null) {
descriptionValue.selectAll();
descriptionValue.cut();
descriptionValue.setText(selectedIssue.getDescription());
}
} else {
displayedIssueLabel.setText("");
displayedBugId = null;
displayedBugProject = null;
}
if (details != null) {
details.setVisible(selectedIssue != null);
}
}
private boolean isVoid(Object o) {
if (o instanceof String) {
return isEmpty((String) o);
} else {
return o == null;
}
}
private boolean isEmpty(String s) {
return s == null || s.trim().isEmpty();
}
private boolean equal(Object o1, Object o2) {
if (isVoid(o1)) {
return isVoid(o2);
}
return o1.equals(o2);
}
private static enum SaveState {
INVALID, UNSAVED, UNCHANGED
}
private final class DetailsData implements Issue {
#Override
public String getId() {
if (displayedBugId == null || isEmpty(displayedIssueLabel.getText())) {
return null;
}
return displayedBugId;
}
#Override
public IssueStatus getStatus() {
if (statusValue == null || isEmpty(statusValue.getText())) {
return null;
}
return IssueStatus.valueOf(statusValue.getText().trim());
}
#Override
public String getProjectName() {
if (displayedBugProject == null || isEmpty(displayedIssueLabel.getText())) {
return null;
}
return displayedBugProject;
}
#Override
public String getSynopsis() {
if (synopsis == null || isEmpty(synopsis.getText())) {
return "";
}
return synopsis.getText();
}
#Override
public String getDescription() {
if (descriptionValue == null || isEmpty(descriptionValue.getText())) {
return "";
}
return descriptionValue.getText();
}
}
private SaveState computeSaveState(Issue edited, Issue issue) {
try {
// These fields are not editable - so if they differ they are invalid
// and we cannot save.
if (!equal(edited.getId(), issue.getId())) {
return SaveState.INVALID;
}
if (!equal(edited.getProjectName(), issue.getProjectName())) {
return SaveState.INVALID;
}
// If these fields differ, the issue needs saving.
if (!equal(edited.getStatus(), issue.getStatus())) {
return SaveState.UNSAVED;
}
if (!equal(edited.getSynopsis(), issue.getSynopsis())) {
return SaveState.UNSAVED;
}
if (!equal(edited.getDescription(), issue.getDescription())) {
return SaveState.UNSAVED;
}
} catch (Exception x) {
// If there's an exception, some fields are invalid.
return SaveState.INVALID;
}
// No field is invalid, no field needs saving.
return SaveState.UNCHANGED;
}
private void updateDeleteIssueButtonState() {
boolean disable = true;
if (deleteIssue != null && table != null) {
final boolean nothingSelected = table.getSelectionModel().getSelectedItems().isEmpty();
disable = nothingSelected;
}
if (deleteIssue != null) {
deleteIssue.setDisable(disable);
}
}
private void updateSaveIssueButtonState() {
boolean disable = true;
if (saveIssue != null && table != null) {
final boolean nothingSelected = table.getSelectionModel().getSelectedItems().isEmpty();
disable = nothingSelected;
}
if (disable == false) {
disable = computeSaveState(new DetailsData(), getSelectedIssue()) != SaveState.UNSAVED;
}
if (saveIssue != null) {
saveIssue.setDisable(disable);
}
}
// Configure the table widget: set up its column, and register the
// selection changed listener.
private void configureTable() {
colName.setCellValueFactory(new PropertyValueFactory<ObservableIssue, String>("id"));
colSynopsis.setCellValueFactory(new PropertyValueFactory<ObservableIssue, String>("synopsis"));
colStatus.setCellValueFactory(new PropertyValueFactory<ObservableIssue, IssueStatus>("status"));
// In order to limit the amount of setup in Getting Started we set the width
// of the 3 columns programmatically but one can do it from SceneBuilder.
colName.setPrefWidth(75);
colStatus.setPrefWidth(75);
colSynopsis.setPrefWidth(443);
colName.setMinWidth(75);
colStatus.setMinWidth(75);
colSynopsis.setMinWidth(443);
colName.setMaxWidth(750);
colStatus.setMaxWidth(750);
colSynopsis.setMaxWidth(4430);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setItems(tableContent);
assert table.getItems() == tableContent;
final ObservableList<ObservableIssue> tableSelection = table.getSelectionModel().getSelectedItems();
tableSelection.addListener(tableSelectionChanged);
}
/**
* Return the name of the project currently selected, or null if no project
* is currently selected.
*
*/
public String getSelectedProject() {
if (model != null && list != null) {
final ObservableList<String> selectedProjectItem = list.getSelectionModel().getSelectedItems();
final String selectedProject = selectedProjectItem.get(0);
return selectedProject;
}
return null;
}
public ObservableIssue getSelectedIssue() {
if (model != null && table != null) {
List<ObservableIssue> selectedIssues = table.getSelectionModel().getSelectedItems();
if (selectedIssues.size() == 1) {
final ObservableIssue selectedIssue = selectedIssues.get(0);
return selectedIssue;
}
}
return null;
}
/**
* Listen to changes in the list selection, and updates the table widget and
* DeleteIssue and NewIssue buttons accordingly.
*/
private final ChangeListener<String> projectItemSelected = new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
projectUnselected(oldValue);
projectSelected(newValue);
}
};
// Called when a project is unselected.
private void projectUnselected(String oldProjectName) {
if (oldProjectName != null) {
displayedIssues.removeListener(projectIssuesListener);
displayedIssues = null;
table.getSelectionModel().clearSelection();
table.getItems().clear();
if (newIssue != null) {
newIssue.setDisable(true);
}
if (deleteIssue != null) {
deleteIssue.setDisable(true);
}
}
}
// Called when a project is selected.
private void projectSelected(String newProjectName) {
if (newProjectName != null) {
table.getItems().clear();
displayedIssues = model.getIssueIds(newProjectName);
for (String id : displayedIssues) {
final ObservableIssue issue = model.getIssue(id);
table.getItems().add(issue);
}
displayedIssues.addListener(projectIssuesListener);
if (newIssue != null) {
newIssue.setDisable(false);
}
updateDeleteIssueButtonState();
updateSaveIssueButtonState();
}
}
private void configureDetails() {
if (details != null) {
details.setVisible(false);
}
if (details != null) {
details.addEventFilter(EventType.ROOT, new EventHandler<Event>() {
#Override
public void handle(Event event) {
if (event.getEventType() == MouseEvent.MOUSE_RELEASED
|| event.getEventType() == KeyEvent.KEY_RELEASED) {
updateSaveIssueButtonState();
}
}
});
}
}
}

PostSharp OnExceptionAspect + EF 6 DbUpdateException

I am using PostSharp to handle Entity Framework 6 exceptions. As you can see in the code below I am handling two different kinds of exceptions:
DbEntityValidationException
DbUpdateException
Now, my HandleExceptionAttribute is able to catch all DbEntityValidationException
But for some reason, HandleExceptionAttribute is never executed whenever EF throws a DbUpdateException
Here is my code so that you have better understanding:
HandleExceptionAttribute.cs
[Serializable]
public class HandleExceptionAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
Exception exception = args.Exception;
var validationException = exception as DbEntityValidationException;
if (validationException != null)
{
HandleDataValidationException(validationException);
}
var updateException = exception as DbUpdateException;
if (updateException != null)
{
HandleDataUpdateException(updateException);
}
throw exception;
}
private void HandleDataUpdateException(DbUpdateException exception)
{
Exception innerException = exception.InnerException;
while (innerException.InnerException != null)
{
innerException = innerException.InnerException;
}
throw new Exception(innerException.Message);
}
private void HandleDataValidationException(DbEntityValidationException exception)
{
var stringBuilder = new StringBuilder();
foreach (DbEntityValidationResult result in exception.EntityValidationErrors)
{
foreach (DbValidationError error in result.ValidationErrors)
{
stringBuilder.AppendFormat("{0} [{1}]: {2}",
result.Entry.Entity.ToString().Split('.').Last(), error.PropertyName, error.ErrorMessage);
stringBuilder.AppendLine();
}
}
throw new Exception(stringBuilder.ToString().Trim());
}
}
MyContext.cs
public class MyContext : DbContext
{
public MyContext () : base(Settings.Get(Settings.DB_CONNECTION_STRING)) { }
public DbSet<Subscriber> Subscribers { get; set; }
private void SetCreatedAtUpdatedAt()
{
foreach (DbEntityEntry entityEntry in ChangeTracker.Entries())
{
switch (entityEntry.State)
{
case EntityState.Added:
((IEntity) entityEntry.Entity).CreatedAt = DateTime.Now;
break;
case EntityState.Modified:
((IEntity) entityEntry.Entity).UpdatedAt = DateTime.Now;
break;
}
}
}
[HandleException]
public override int SaveChanges()
{
SetCreatedAtUpdatedAt();
return base.SaveChanges();
}
[HandleException]
public override Task<int> SaveChangesAsync()
{
SetCreatedAtUpdatedAt();
return base.SaveChangesAsync();
}
}
Action
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Subscribe(string email)
{
string message = null;
bool success = false;
try
{
using (var context = new MyContext())
{
context.Subscribers.Add(
new Subscriber
{
Email = email
});
await context.SaveChangesAsync();
}
await _queueManager.Enque(
QueueNames.TASK_SEND_EMAIL,
new BrokeredMessage(email),
Settings.Get(Settings.SB_CN_TASKS_SEND));
success = true;
}
catch (Exception exception)
{
// Whenever there is a DbUpdateException, it does not get
// filtered and processed by PostSharp Exception Handler
// I have a unique index constraint on the "Email" field of the Subscriber.
// So when I try to add a duplicate subscriber, EF raises DbUpdateException
// This exception should have been filtered by PostSharp since I have
// overridden and decorated "SaveChangesAsync()" method in my DbContext
// with [HandleException]
// On the other hand, I also have [Required] for "Email" in my POCO.
// So, when I don't pass in any email address for the subscriber,
// EF raises DbEntityValidationException -- this does get processed
// by the PostSharp Exception Handler
message = exception.Message;
}
return Json(new {message, success});
}
PostSharp does not currently support async methods. They have announced that they will support async starting with PostSharp 3.1.

Is EntityReference.Load checking for EntityReference.IsLoaded?

Hi I was wondering if EntityReference.Load method includes
If Not ref.IsLoaded Then ref.Load()
My question is basically:
Dim person = Context.Persons.FirstOrDefault
person.AddressReference.Load()
person.AddressReference.Load() 'Does it do anything?
It does Load again. I verified this by Profiler and it shown two queries. Default merge option is MergeOption.AppendOnly and it doesn't prevent from querying again. Code from Reflector:
public override void Load(MergeOption mergeOption)
{
base.CheckOwnerNull();
ObjectQuery<TEntity> query = base.ValidateLoad<TEntity>(mergeOption, "EntityReference");
base._suppressEvents = true;
try
{
List<TEntity> collection = new List<TEntity>(RelatedEnd.GetResults<TEntity>(query));
if (collection.Count > 1)
{
throw EntityUtil.MoreThanExpectedRelatedEntitiesFound();
}
if (collection.Count == 0)
{
if (base.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
{
throw EntityUtil.LessThanExpectedRelatedEntitiesFound();
}
if ((mergeOption == MergeOption.OverwriteChanges) || (mergeOption == MergeOption.PreserveChanges))
{
EntityKey entityKey = ObjectStateManager.FindKeyOnEntityWithRelationships(base.Owner);
EntityUtil.CheckEntityKeyNull(entityKey);
ObjectStateManager.RemoveRelationships(base.ObjectContext, mergeOption, (AssociationSet) base.RelationshipSet, entityKey, (AssociationEndMember) base.FromEndProperty);
}
base._isLoaded = true;
}
else
{
base.Merge<TEntity>(collection, mergeOption, true);
}
}
finally
{
base._suppressEvents = false;
}
this.OnAssociationChanged(CollectionChangeAction.Refresh, null);
}
Just for reference for anyone else finding the accepted answer, here is the extension method I created for my current project.
using System.Data.Objects.DataClasses;
namespace ProjectName
{
public static class EntityFrameworkExtensions
{
public static void EnsureLoaded<TEntity>(this EntityReference<TEntity> reference)
where TEntity : class, IEntityWithRelationships
{
if (!reference.IsLoaded)
reference.Load();
}
}
}
And usage:
Patient patient = // get patient
patient.ClinicReference.EnsureLoaded();
patient.Clinic.DoStuff();