0%

Group Policy Precedence

GPO in AD Domain Controller will override the local GPO
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/policy/group-policy-hierarchy

Command line to export GPO

secedit /export /areas USER_RIGHTS /cfg OldUserRights.inf
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/secedit

User Rights Assignment

https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment

We usually need SeBatchLogonRight and SeServiceLogonRight

IIS full installation will require IIS_IUSRS to have SeImpersonatePrivilege. Will get 500 error if the right is missing.
https://serverfault.com/questions/50160/500-error-when-using-custom-account-for-application-pool-in-iis-7

Splunk required rights

Microsoft disabled Basic Auth over HTTP with PSRP on Linux. See here

We have to use Negotiate / Kerberos to remote to windows.

But using WinRM is very very unstable on linux. Microsoft is suggesting to install ssh on windows box.

With official powershell docker image

docker run -it --rm mcr.microsoft.com/powershell

We have to run apt-get update && apt-get install netbase to make it work. The related issue is here

The microsoft/powershell image is based on Ubuntu, which does not bundle /etc/services, so you are likely being bit by this issue: microsoft/omi#623.

Known dependencies on linux

Many issues targets to . It has some documents about setting up ntlm and kerberos.

The mentioned special packages are krb5 and gss-ntlmssp.

I am not quite sure about this part yet. Just record here for now.

最近用mac的chrome遇到了一个很烦人的问题,每次新建一个profile的时候,chrome都会提示自动安装了fuze,记录一下解决方案。

我开始的时候用google搜索了很久都没有找到相应的解决方案,甚至研究了chrome的一些配置,但是太过复杂,不得不放弃。

后来终于在Google Chrome Help Forum搜索fuze得到了这样一个问题

Hello,

I installed a Chrome extension called ‘Fuze on Chrome’ in October 2016. I’ve tried to delete it through Chrome Extensions Settings, however, every time I create a new Chrome profile on this computer, Fuze on Chrome automatically installs. I can’t find Fuze on Chrome in the Chrome Web Store anymore. How do I delete this extension from my local machine for good?

Other funky behavior:

  1. In ‘chrome://extensions’, when I click Trash Icon > Check the checkbox for Report Abuse > Click ‘Remove’ , I receive a 404 error and I am redirected to this URL: https://chrome.google.com/webstore/report/kcehcblfpidimbihdfophhhdejckolgh?utm_source=chrome-remove-extension-dialog.

  2. I cannot find the folder with its corresponding Developer ID under this directory: ~/Library/Application Support/Google/Chrome/Default/Extensions

  3. I tried deleting all key references of the developer id and its corresponding values within the ~/Library/Application Support/Google/Chrome/Default/Preferences file, but it somehow gets populated again after I rewrite it. (Apologies if this is standard behavior, I’m not familiar with the Chrome Extension development process).

  4. I’ve tried deleting the Chrome application from my system and reinstalling it, but Fuze automatically gets reinstalled. It is also showing up when I reinstall Chrome Canary.

Any assistance would be greatly appreciated!

Thanks,
S

答案是

Hi, I figured out to delete it. Go into:

“/Library/Application Support/Google/Chrome/External Extensions”

and delete the file called: “kcehcblfpidimbihdfophhhdejckolgh.json”

这个目录是chrome提供的自动安装extension的一种方式,详细可以参考官方文档

什么是pipenv

Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world.

Pipenv是pip与virtualenv的结合,可以自动创建python虚拟环境,方便开发和管理依赖。

当我们使用virtualenv来创建虚拟环境的时候,我们需要制定一个目录,通常的做法是放在当前项目的env目录下,然后source env/bin/activate

但我们并不希望将env提交到git仓库中,那么其他人想要开发就需要重新生成这个目录,每次开发都需要执行一次source。pipenv为我们解决了这样的问题,它可以让你忽略virtualenv的存在,只需要使用pipenv的命令就可以拥有方便的开发环境。

pipenv自动创建virtualenv的convention是什么?

在mac中可以看到pipenv生成的virtualenv默认位于像这样的目录中

$HOME/.local/share/virtualenvs/projectname-hashcode/

那么后面的hashcode究竟是如何生成的呢?我阅读了下pipenv源码研究了下。

pipenv/project.py中有一个方法来获得virtualenv的location

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@property
def virtualenv_location(self):
# if VIRTUAL_ENV is set, use that.
if PIPENV_VIRTUALENV:
return PIPENV_VIRTUALENV

if not self._virtualenv_location: # Use cached version, if available.
assert self.project_directory, "project not created"
self._virtualenv_location = self.get_location_for_virtualenv()
return self._virtualenv_location

def get_location_for_virtualenv(self):
if self.is_venv_in_project():
return os.path.join(self.project_directory, ".venv")

name = self.virtualenv_name
if self.project_directory:
venv_path = os.path.join(self.project_directory, ".venv")
if os.path.exists(venv_path) and not os.path.isdir(".venv"):
with io.open(venv_path, "r") as f:
name = f.read().strip()
# Assume file's contents is a path if it contains slashes.
if looks_like_dir(name):
return vistir.compat.Path(name).absolute().as_posix()
return str(get_workon_home().joinpath(name))

当选择在项目内生成venv时,目录名是.venv,默认会使用计算的self.virtualenv_name

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@property
def virtualenv_name(self):
sanitized, encoded_hash = self._get_virtualenv_hash(self.name)
suffix = "-{0}".format(PIPENV_PYTHON) if PIPENV_PYTHON else ""
# If the pipfile was located at '/home/user/MY_PROJECT/Pipfile',
# the name of its virtualenv will be 'my-project-wyUfYPqE'
return sanitized + "-" + encoded_hash + suffix

def _get_virtualenv_hash(self, name):
"""Get the name of the virtualenv adjusted for windows if needed

Returns (name, encoded_hash)
"""

def get_name(name, location):
name = self._sanitize(name)
hash = hashlib.sha256(location.encode()).digest()[:6]
encoded_hash = base64.urlsafe_b64encode(hash).decode()
return name, encoded_hash[:8]

clean_name, encoded_hash = get_name(name, self.pipfile_location)
venv_name = "{0}-{1}".format(clean_name, encoded_hash)

# This should work most of the time for
# Case-sensitive filesystems,
# In-project venv
# "Proper" path casing (on non-case-sensitive filesystems).
if (
fnmatch.fnmatch("A", "a")
or self.is_venv_in_project()
or get_workon_home().joinpath(venv_name).exists()
):
return clean_name, encoded_hash

# Check for different capitalization of the same project.
for path in get_workon_home().iterdir():
if not is_virtual_environment(path):
continue
try:
env_name, hash_ = path.name.rsplit("-", 1)
except ValueError:
continue
if len(hash_) != 8 or env_name.lower() != name.lower():
continue
return get_name(env_name, self.pipfile_location.replace(name, env_name))

# Use the default if no matching env exists.
return clean_name, encoded_hash

这就是pipenv计算hash的方式,可以看到用来生成hash的是self.pipfile_location,让我们来确认下这个的值会是什么?

1
2
3
4
5
6
7
8
9
10
11
12
@property
def pipfile_location(self):
if PIPENV_PIPFILE:
return PIPENV_PIPFILE

if self._pipfile_location is None:
try:
loc = pipfile.Pipfile.find(max_depth=PIPENV_MAX_DEPTH)
except RuntimeError:
loc = None
self._pipfile_location = _normalized(loc)
return self._pipfile_location

pipenv/patched/pipfile/api.py中找到了find方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Pipfile(object):
@staticmethod
def find(max_depth=3):
"""Returns the path of a Pipfile in parent directories."""
i = 0
for c, d, f in walk_up(os.getcwd()):
i += 1

if i < max_depth:
if 'Pipfile':
p = os.path.join(c, 'Pipfile')
if os.path.isfile(p):
return p
raise RuntimeError('No Pipfile found!')

location将会是Pipfile的absolute path,也就是项目的根目录的绝对路径,pipenv使用这个绝对路径来生成一个hash避免同名项目目录的冲突。

How to get indexes of current database?

1
select * from sys.indexes

How to get replication articles?

1
2
3
4
5
6
7
8
9
10
11
SELECT 
msp.publication AS PublicationName,
msa.publisher_db AS DatabaseName,
msa.article AS ArticleName,
msa.source_owner AS SchemaName,
msa.source_object AS TableName
FROM distribution.dbo.MSarticles msa
JOIN distribution.dbo.MSpublications msp ON msa.publication_id = msp.publication_id
ORDER BY
msp.publication,
msa.article
1
2
select * from syspublications
select * from sysarticles where pubid = 3

Useful replication stored procedure.

1
2
3
4
5
6
7
8
9
exec sp_dropsubscription
@publication='**-Publication',
@article= N'all',
@subscriber = 'WIN-VPE**FSH8IJ'

exec sp_droppublication
@publication='**-Publication'

exec sp_removedbreplication @dbname='**-local'

How to close connect and drop db in sql server?

1
2
alter database [dbname] set SINGLE_USER with rollback immediate
drop database [dbname]

Other collections

arguments

先从问题出发

1
2
3
4
5
6
7
(function () {
try {
throw arguments.map(x => x * 3);
} catch (e) {
console.log(e);
}
})(1, 2, 3)

结果是什么呢?大家可以复制到console中尝试下。

从代码可以看到我们使用了arguments,这是javascript function的特殊变量,用来表示整个参数列表,是一个Array like的对象,为什么说它是Array like的对象呢?因为arguments并不是一个Array对象,所以上面问题的结果是Uncaught TypeError: arguments.map is not a function,可以看到arguments并不是真正的Array对象,那么如何让上面的代码输出[3, 6, 9]这样的结果呢?

ES6前的javascript代码通常需要这样写

1
2
3
4
5
6
7
(function () {
try {
throw Array.prototype.map.call(arguments, function (x) { return x * 3;});
} catch (e) {
console.log(e);
}
})(1, 2, 3)

或者将其转化为数组再应用map这样的数组方法

1
2
3
4
5
6
7
8
(function () {
try {
throw Array.prototype.slice.call(arguments)
.map(function (x) { return x * 3;});
} catch (e) {
console.log(e);
}
})(1, 2, 3)

那么在ES6中我们可以怎样实现呢?

1
2
3
4
5
6
7
((...args) => {
try {
throw args.map(x => x * 3);
} catch (e) {
console.log(e);
}
})(1, 2, 3)

或着更简洁的转化Array like为Array的方法

1
2
3
4
5
6
7
(function () {
try {
throw Array.from(arguments).map(x => x * 3);
} catch (e) {
console.log(e);
}
})(1, 2, 3)

无论哪种看起来都比ES5的实现漂亮很多,这里Array.from是ES6中新增的一个用来将类数组对象转化为数组对象的方法,前面我们提到了多次Array like对象,下面的对象就是Array like的

1
2
3
4
5
6
7
var arrayLike = {
"0": 9,
"2": 8,
"1": 7,
length: 3
}
console.log(Array.from(arrayLike)) // [9, 7, 8]

rest arguments

我们再看下另外一种ES6实现当中的...args,看起来似乎和Java的变长参数很像,这在ES6的语法中叫做剩余参数,使用剩余参数可以代替arguments,比如前面提到的例子。剩余参数叫做剩余参数,当然也可以和正常参数一起使用,比如

1
2
3
4
function sum(a, ...args) {
return args.reduce((x,y) => x + y, a);
}
console.log(sum(1,2,3,4,5));

需要注意,rest参数只能是最后一个参数,不能再有其他参数,否则会报错。

default arguments

除了rest参数,ES6还提供了默认参数的功能,我们先看一个问题

1
2
3
4
5
6
7
function log(x, y) {
y = y || 'World';
console.log(x, y);
}
log('Hello');
log('Hello', 'China');
log('Hello', '');

三个log分别是什么结果呢?结果都是Hello China,第三个log的结果和我们调用的预期是不一样的,那么如何避免呢?

1
2
3
4
5
6
7
8
9
// 写法一
if (typeof y === 'undefined') {
y = 'World';
}

// 写法二
if (arguments.length === 1) {
y = 'World';
}

那么使用了ES6的默认参数后是就可以直接按照问题的写法去写了

1
2
3
4
5
6
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello');
log('Hello', 'World');
log('Hello', '');

默认参数最大的好处就是可以直接从函数参数表知道哪些参数是可选参数,而不用具体阅读其实现。

destructuring

Quiz

1
2
3
var a = 3, b = 4;
[a, b] = [b, a];
console.log(a, b);

用过python或者ruby的同学对这种写法一定已经非常熟悉了,现在ES6也支持这种fancy的特性了,这种语法被叫做解构

1
2
3
4
5
6
7
8
9
10
var [a, [[b], c]] = [1, [[2], 3]];
console.log(a,b,c);
var [ , , third] = ["foo", "bar", "baz"];
console.log(third);
var [x, , y] = [1, 2, 3];
console.log(x,y);
var [head, ...tail] = [1, 2, 3, 4];
console.log(head,tail);
var [x, y, ...z] = ['a'];
console.log(x,y,z);

解构也可以有默认值

1
2
3
4
5
6
var [y = 3] = [];
console.log(y);
var [x, y = 3] = ['a'];
console.log(x, y);
var [x = 3, y = 4] = [undefined, 1]
console.log(x, y);

可以对数组解构,也可以对对象结构,那么对象的解构是什么样的呢?

1
2
3
4
5
6
7
8
var {foo: x, bar: y} = {foo: 'aaa', bar: 'bbb'};
console.log(x);
console.log(y);

var { prop, prop2} = {prop: 5, prop2: 10};
console.log(prop, prop2);


那么函数的参数也可以写成这样的形式

1
2
3
4
5
6
7
8
function foo({x, y = 5}) {
console.log(x, y);
}

foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // TypeError: Cannot read property 'x' of undefined

解构有很多用途,比如可以做这种事情

1
2
3
4
5
6
7
8
var something = [
{url: 'baidu.com'},
{url: 'google.com'},
{url: 'facebook.com'}
];
//pluck
var urls = something.map(({ url }) => url);
console.log(urls);

但对象的解构需要注意,如果将声明与实现分开,需要将表达式放置于括号中

1
2
3
4
5
6
7
8
var a, b;
{a,b} = {a:3,b:4};
console.log(a,b);
//error

var a, b;
({a,b} = {a:3,b:4});
console.log(a,b);

命令行的哲学与快捷键的哲学非常相似,为什么快捷键可以提高我们的效率, 因为鼠标操作需要经历手离开键盘移到鼠标上、移动定位按钮、点击、手移回键盘上的过程,而使用快捷键往往只需要按键盘上的几个键就可以完成同样的任务,如果鼠标操作需要1到2秒,那么快捷键操作通常只要0点几秒。为什么需要命令行操作道理也是一样的。

在linux的世界中, 可以通过命令行高效的完成很多事情, 比如常见的ls, grep, cat等等, 因为这些工具的存在, linux程序员几乎可以在命令行下完成所有的工作, 这种工作方式既极客又高效, 习惯了这种工作方式后就再也不想用鼠标了。

但并不是所有时候都能使用mac或者linux进行编程工作的,我们不得不去面对缺乏命令行工具的windows世界,虽然有着宇宙最强ide,但这并不能取代命令行给我们带来的高效。那么在windows下有没有办法高效的利用命令行呢?答案是肯定的。

powershell

powershell是windows为了取代cmd而产生的命令行工具,powershell提供了比linux shell更好的语法,但这并不能改变windows下命令行程序缺乏这一致命缺陷。如今流行的工具都会提供windows版本,比如nodejs,比如git,这在一定程度上缓解了windows下命令行不好用的问题。我曾经写了一篇介绍conemu的文章,介绍了以bat文件为基础快速启动命令行并配置好常用的环境变量的方式。

这里将介绍另一种快速启动命令行的方式,以及快速启动常用程序的方式

在windows中,lnk文件代表快捷方式,往往我们都是通过在桌面或者开始菜单建立快捷方式来快速打开某个程序,大部分程序在安装过程也会帮我们完成这些事情,但这仍然需要大量的鼠标操作。lnk文件正是我们要做到快速启动程序的关键,lnk文件可以在windows的Run中省略后缀打开,比如打开处于环境变量中z.lnk文件只需要四个键即可完成,Win + R z Enter

所以在windows下我的设置是这样的

  • 将某个常用的目录加入环境变量path中比如C:\chenbojian
  • 将指向conemu的快捷方式z.lnk放入该目录中
  • 快捷键快速启动并享受命令行。

这样启动powershell后会从$PROFILE中加载环境,如果你懂一些powershell的语法就可以像写.bashrc一样轻松的调教你的powershell,让他支持你喜欢的命令,比如我增加了vim的aliasSet-Alias vi path/to/gvim.exe,你也可以添加你喜欢的编辑器比如vscode,sublime等。这样我们就得到了类似linux命令行的体验了。

something else

使用powershell以及快捷键虽然得到了很好的体验,但仍然有着极大的差距,这主要因为windows的编译工具链与linux系的差别,linux程序往往都是通过源码发布的,然后在用户机器上编译得到可执行文件,这主要依赖于Linux中广泛存在多年的automake工具链,但windows并没有automake工具链,这使得windows下从源码编译变得异常困难,这使得很多好用的linux工具无法及时在windows下得到更新。

windows下也存在着cygwin和msys2这样的让linux程序直接在windows下编译的工具,我也曾经使用过,但windows下总有些别扭,尤其是字符集的不一致导致乱码问题。windows虽然内核早已使用unicode,但是对于中文支持确是一直使用了gbk的方式,比如chcp65001后就无法输入中文的命令行,种种因素使得windows下使用linux工具不够完美的体验。

随着windows10的发布windows似乎正在做着一系列的事情来吸引开源开发者对windows平台的关注,希望windows能在开源的世界中重新焕发活力。

merge 与 update

对于transient对象,指明id后,可以使用merge来更新对应数据库条目,也可以使用update来更新,但是如果当前session中存在该id的记录,使用update会抛出异常.

对于detached对象,两者相似,update会将对象持久化,merge不会改变对象状态?(待验证)

对于persist对象,两者相同?(待验证)

merge 与 persist

persist会将对象持久化,merge不会,其他方面类似,比如如下代码

1
2
3
4
User user = new User();
user.setName("good user");
sessionFactory.getCurrentSession().merge(user);
//user.getId() == 0;

merge后会执行insert语句,但并不会改变user的状态,user.id==0

1
2
3
4
User user = new User();
user.setName("good user");
sessionFactory.getCurrentSession().persist(user);
//user.getId() != 0;

persist后也会执行insert语句,但会改变user的状态为persistent,user.id!=0,修改user的属性在transaction结束后会更新到数据库中.

参考stackoverflow回答

orphanRemoval=true 与 cascade=CascadeType.DELETE

孤值删除包括了级联删除的情况. 同时孤值删除还会处理额外的情况, 当断开关系后update时会自动删除有外键的一方.

hibernate继承

注解方式example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "field", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("dummy")
public class EntitySuperClass {
// here definitions go
// but don't define discriminator column here
}

@Entity
@DiscriminatorValue(value="sub1")
public class Sub1Class extends EntitySuperClass {
// here definitions go
}

hibernate在jsp中lazyloading失效的解决方法

配置enable_lazy_load_no_trans为true

未完待续…

ConEmu

终于不用忍受原始cmd或者powershell难看的界面和难看的字体了。

目前存在一个小问题,我之前一般会把常用的环境变量配置在一个bat文件中,比如cbjps.bat,每次要启动命令行只需要WIN+R,然后输入cbjps即可解决。之前的bat代码如下:

1
2
3
4
5
@echo off
set path=%path%;C:\python27
set path=%path%;C:\python27\scripts
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
powershell

用了ConEmu之后将powershell改成start PATH\TO\ConEmu\ConEmu.exe后可以使用,但是会一闪而过一个cmd窗口,并且ConEmu的窗口不会自动前置,强迫症表示无法忍受,于是想到了用没有窗口的pythonw来启动,解决了窗口不会自动前置的问题。

1
2
3
4
5
@echo off
set path=%path%;C:\python27
set path=%path%;C:\python27\scripts
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
pythonw D:\chenbojian\cbjtool\ConEmu\conemu.pyw

python代码就非常简单了

1
2
import subprocess as sp
sp.Popen(r"D:\chenbojian\cbjtool\ConEmu\ConEmu64.exe")

不过有个一闪而过的窗口还没能解决,困难点主要在于cmd可以通过call***.bat来设置环境变量,而powershell简单的这么做,不然就可以把所有的环境配置到powershell的$PROFELE的文件中了,列一下我的$PROFILE内容

1
2
3
4
5
6
7
8
9
$env:PATH=$env:PATH+";C:\Program Files\iojs\"+";"+$env:APPDATA+"\npm"
$env:JAVA_HOME='C:\Program Files\Java\jdk1.8.0_20'
set-alias 'vi' 'gvim'
set-alias 'gradle' 'D:\chenbojian\cbjtool\gradle-2.4\bin\gradle.bat'
set-alias 'mvn' 'D:\chenbojian\cbjtool\apache-maven-3.3.3\bin\mvn.cmd'
import-module PsGet

# Load posh-git example profile
. 'C:\Users\johr\Documents\WindowsPowerShell\Modules\posh-git\profile.example.ps1'

据说Powershell Community Extension可以解决问题,有个Invoke-batch命令可以从bat文件读取环境变量,有空研究下。

update

安装了Powershell Community Extension后可以Invoke-batch,也可以直接Import-visualstudiovars来加载vs编译器的环境变量,这样就不需要先从一个bat文件启动conEmu了。windows的运行(WIN+R)可以直接启动快捷方式文件,比如环境变量目录中有cbjps.lnk,只需要WIN+R,然后cbjps即可启动快捷方式对应的程序。不过注册表右键菜单对应项需要直接指向原始exe文件才行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$env:PATH += ";C:\Program Files\iojs\" 
$env:PATH += ";" + $env:APPDATA + "\npm"
$env:PATH += ";C:\Python27\"
$env:PATH += ";C:\Python27\scripts\"
# Invoke-BatchFile "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
function vs {
Import-VisualStudioVars 2013 x64
}
$env:JAVA_HOME='C:\Program Files\Java\jdk1.8.0_20'
set-alias 'vi' 'gvim'
set-alias 'gradle' 'D:\chenbojian\cbjtool\gradle-2.4\bin\gradle.bat'
set-alias 'mvn' 'D:\chenbojian\cbjtool\apache-maven-3.3.3\bin\mvn.cmd'
import-module PsGet

# Load posh-git example profile
. 'C:\Users\johr\Documents\WindowsPowerShell\Modules\posh-git\profile.example.ps1'

未完待续。。。

查看原文

##Cascading Remove

Marking a reference field with CascadeType.REMOVE (or CascadeType.ALL, which includes REMOVE) indicates that remove operations should be cascaded automatically to entity objects that are referenced by that field (multiple entity objects can be referenced by a collection field):

1
2
3
4
5
@Entity
class Employee {
@OneToOne(cascade=CascadeType.REMOVE)
private Address address;
}

##Orphan Removal

JPA 2 supports an additional and more aggressive remove cascading mode which can be specified using the orphanRemoval element of the @OneToOne and @OneToMany annotations:

1
2
3
4
5
@Entity
class Employee {
@OneToOne(orphanRemoval=true)
private Address address;
}

##DIFFERENCE:

The difference between the two settings is in the response to disconnecting a relationship. For example, such as when setting the address field to null or to another Address object.

If orphanRemoval=true is specified the disconnected Address instance is automatically removed. This is useful for cleaning up dependent objects (e.g. Address) that should not exist without a reference from an owner object (e.g. Employee).
If only cascade=CascadeType.REMOVE is specified no automatic action is taken since disconnecting a relationship is not a remove operation.