如何建模软件包、版本和许可证? [英] How to model packages, versions and licenses?
问题描述
我现在有点卡住了.问题在于 npm 包、它们的版本/发行版和许可证.
I'm currently a bit stuck. The question is around npm packages, their versions/releases and their licenses.
这是一个简单的许可证
CREATE TABLE IF NOT EXISTS license (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
reference TEXT NOT NULL,
is_deprecated_license_id BOOLEAN NOT NULL,
reference_number INTEGER NOT NULL,
license_id TEXT NOT NULL,
is_osi_approved BOOLEAN NOT NULL
);
INSERT INTO license
("name",reference,is_deprecated_license_id,reference_number,license_id,is_osi_approved)
VALUES
('Academic Free License v2.0','./AFL-2.0.json',false,0,'AFL-2.0',true);
这是我的包裹
CREATE TABLE IF NOT EXISTS npm_package (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL
);
INSERT INTO npm_package
(name, description)
VALUES
('react', 'React is a JavaScript library for building user interfaces.'),
('react-router-dom', 'DOM bindings for React Router'),
('typescript', 'TypeScript is a language for application scale JavaScript development'),
('react-dom', 'React package for working with the DOM.');
一个包有多个版本,每个版本都有许可证,例如
A package has multiple versions and each version has license, e.g.
- 反应 - 1.0.0 - 麻省理工学院
- 反应 - 2.0.0 - BSD
- 反应 - 3.0.0 - 麻省理工学院
- ...
版本只是一个semver字符串.
The version is just a semver string.
CREATE TABLE IF NOT EXISTS npm_version (
npm_package_id BIGINT NOT NULL REFERENCES npm_package,
version TEXT NOT NULL,
license_id INTEGER NOT NULL REFERENCES license
)
现在我正在尝试使用 Spring Boot 和 Hibernate 对此进行建模.这是我到目前为止所得到的.
Now I'm trying to model this with Spring Boot and Hibernate. Here is what I've got so far.
@Entity
public class License {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String reference;
private Boolean isDeprecatedLicenseId;
private Integer referenceNumber;
private String name;
private String licenseId;
private Boolean isOsiApproved;
}
这是我的 npm 包.
And here is my npm package.
@Entity
public class NpmPackage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
}
现在我想合并软件包、它们的版本和它们的许可证.我将如何继续使用 Hibernate?我正在寻找的查询类似于给我所有带有相应许可证的 'react' 版本"
Now I want to combine packages, their versions and their licenses. How would I proceed using Hibernate? The query I'm looking for is something like "Give me all releases for 'react' with their according license"
非常感谢!
编辑 24/03/2021
Edit 24/03/2021
我做了更多的研究,并取得了更进一步的进展.让我们暂时移除许可证并专注于包和版本.
I did some more research and got a bit further. Let's remove the license for now and focus and packages and versions.
这是我创建包的方法.
CREATE TABLE IF NOT EXISTS npm_package (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL
);
INSERT INTO npm_package
(name, description)
VALUES
('react', 'React is a JavaScript library for building user interfaces.'),
('react-router-dom', 'DOM bindings for React Router'),
('typescript', 'TypeScript is a language for application scale JavaScript development'),
('react-dom', 'React package for working with the DOM.');
这是我创建版本的方法.版本不应该需要额外的标识符.包和版本的组合是独一无二的.
Here is how I create a version. A version should not need an extra identifier. The combination of package and version is unique.
CREATE TABLE IF NOT EXISTS npm_package_version (
npm_package_id BIGINT NOT NULL REFERENCES npm_package,
version TEXT NOT NULL,
UNIQUE(npm_package_id, version)
)
这里是NpmPackage.java
@Entity
public class NpmPackage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany
private List<NpmPackageVersion> versions;
private String name;
private String description;
}
这里是NpmPackageVersion.java
@Entity
public class NpmPackageVersion {
@EmbeddedId
private NpmPackageIdVersion npmPackageIdVersion;
@MapsId("npmPackageId")
@ManyToOne
private NpmPackage npmPackage;
@Embeddable
public class NpmPackageIdVersion implements Serializable {
private static final long serialVersionUID = 3357194191099820556L;
private Long npmPackageId;
private String version;
}
}
没有 @MapsId
我得到了
表 [npm_package_version] 包含多个逻辑列名引用的物理列名 [npm_package_id]:[npm_package_id]、[npmPackageId]
Table [npm_package_version] contains physical column name [npm_package_id] referred to by multiple logical column names: [npm_package_id], [npmPackageId]
使用 @MapsId
我得到
架构验证:表 [npm_package_versions] 中缺少列 [versions_npm_package_id]
Schema-validation: missing column [versions_npm_package_id] in table [npm_package_versions]
当我将列重命名为 versions_npm_package_id
我得到
When I rename the column to versions_npm_package_id
I get
架构验证:表 [npm_package_versions] 中缺少列 [npm_package_id]
Schema-validation: missing column [npm_package_id] in table [npm_package_versions]
我绕着圈子跑,哪儿也去不了.很久没有觉得自己这么蠢了.我还在等待点击"每当我开始使用新技术时的事件.不幸的是,这还没有发生:)
I'm running in circles and not getting anywhere. Never felt so stupid in a long time. I'm still waiting for the "click" event whenever I start working with new technology. That unfortunately hasn't happened yet :)
有什么想法吗?
推荐答案
您已经接近找到解决方案了.
You were pretty close to the finding the solution.
以下设置有效:
NpmPackage
@Entity
@Table(name = "npm_package")
public class NpmPackage {
public NpmPackage(String name, String description) {
this.name = name;
this.description = description;
}
public NpmPackage() {
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
@OneToMany(mappedBy = "npmPackage", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<NpmPackageVersion> versions = new ArrayList<>();
...//getters and setters
public void addVersion(NpmPackageVersion version) {
this.versions.add(version);
version.setNpmPackage(this);
}
public void removeVersion(NpmPackageVersion version) {
this.versions.remove(version);
}
}
NpmPackageVersion
@Entity
@Table(name = "npm_package_version")
public class NpmPackageVersion {
public NpmPackageVersion(String version, License license) {
setVersion(version);
this.license = license;
}
public NpmPackageVersion() {
}
@EmbeddedId
private NpmPackageIdVersion npmPackageIdVersion = new NpmPackageIdVersion();
@MapsId("npmPackageId")
@ManyToOne
private NpmPackage npmPackage;
@ManyToOne
private License license;
public String getVersion() {
return npmPackageIdVersion.version;
}
public void setVersion(String version) {
npmPackageIdVersion.version = version;
}
...//getters and setters
@Embeddable
public static class NpmPackageIdVersion implements Serializable {
private static final long serialVersionUID = 3357194191099820556L;
private Long npmPackageId;
private String version;
... //getters and setters etc.
}
}
许可证
@Entity
@Table(name = "license")
public class License {
public License() {}
public License(String name, String licenseId) {
this.name = name;
this.licenseId = licenseId;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String reference;
@Column(name = "is_deprecated_license_id")
private boolean deprecatedLicenseId;
private Integer referenceNumber;
private String name;
private String licenseId;
@Column(name = "is_osi_approved")
private boolean osiApproved;
... //getters and setters
}
我使用以下代码进行测试:
I used the following code to test it:
@Transactional
public NpmPackage createPackage() {
License license = new License("General Public License", "GPL 2.0");
em.persist(license);
NpmPackage npmPackage = new NpmPackage("react", "React Framework");
npmPackage.addVersion(new NpmPackageVersion("8.11.0", license));
em.persist(npmPackage);
}
这篇关于如何建模软件包、版本和许可证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!